---
title: 'GraphQL: The Case of the Missing Fields'
teaser: Because who doesn't like a good ole mystery?
tags: testing,web,architecture,debugging
author: EJ Mitchell
published_on: 2019-10-14
---

It goes without saying that debugging issues between the frontend and backend of
a codebase can be frustrating. But, it's _also_ like solving a mystery! As with
any juicy case, it's good to make sure the steps towards the solution are
written down to help future sleuths.

When framed in this way, I always think it makes the debugging/documenting
process less of a chore and more like being Sherlock Holmes. So come along, dear
Watson: we have a case to investigate!

## The Case

We added some new fields to a GraphQL object in the backend. This feature work
was tested and approved, so we began updating the frontend to display the new
information. Upon starting development, however, we noticed that the new fields
_weren't showing up_ in the frontend's generated version of the GraphQL logic.
  
Where were those fields? We could see them and interact with them in the
backend, but why weren’t they joining us in the frontend?
  
At this point, we knew we had a debugging task on our hands, so the Chrome
developer tools were opened to the Network tab. There, we could review requests
and responses. Lo and behold, even if we _manually_ added the missing fields to
the frontend, our request to GraphQL was throwing a 400 error. It was claiming
that the new fields we had added didn't exist on the GraphQL object. (_This is
where it's appropriate to take out a pipe and chew on it ponderously._)

So, the case was officially opened: **Was it the frontend or the backend that**
**was responsible for the missing fields?**
  
The tricky thing about modular apps: it can be difficult to place the failure on
one side or the other. As a result, I’ve found that it is better to **debug one**
**side at a time**. Since we discovered the issue working with the frontend, we
started there.

### The frontend

The first thing that stuck out to us was that our frontend was trying to use an
older version of the GraphQL objects. Why? It occurred to us that maybe
_something_ was cached. Resetting caches is always a good first step, especially
since **caches can show up in unexpected places**.  (Looking at you,
[Jest](https://jestjs.io/docs/en/troubleshooting#caching-issues).)  After each
cache we cleared, we ran the script that regenerated our GraphQL objects to see
if there were any changes. No dice.
  
We then moved on to deleting and regenerating the package directory (e.g.,
`node_modules` or `elm_stuff`). This is an especially helpful thing to do if
your problem extends beyond the current example and ventures into "build error"
territory. We reran the script to see if _that_ fixed anything. Nope.
  
After we exhausted our methods for testing the frontend and found nothing wrong,
we started investigating the backend.

### The backend

With compiled languages, you get a bonus technique for finding red flags: errors
before your code can even run. Since the backend was written in
[Scala](https://www.scala-lang.org/), the first thing we did was run the
compiler. Maybe something was accidentally typed into a file or a line was added
on the latest pull of the feature branch we didn't catch. **It's always a good**
**starting point to (re-)compile if you have the capability to do so.**
  
Unsurprisingly, though, this was not the issue. We found nothing had been
changed in the files save for the new GraphQL fields we already knew were there.
Even the tests were all (still) passing. With nowhere to turn, we went to a
third party to figure out once and for all: which end of our codebase was truly
incorrect?

### Introducing a third party

#### AKA: Interviewing the Witness

Sometimes this is just [another human](http://gph.is/2d2tlp9) to talk the issue
through with. Maybe they can point out something you cannot see after spending
several hours dragging your eyes down the same thousands of lines. There is also
another debugging technique called ["rubber
ducking"](https://www.thoughtfulcode.com/rubber-duck-debugging-psychology/),
where you talk to an inanimate object about the issue you are trying to solve.
In fact someone even bought a [domain name](https://rubberduckdebugging.com/) to
dedicate a page to the subject.

![Sherlock leaning with his head next to a
skull](https://images.thoughtbot.com/blog-vellum-image-uploads/33czEE9TTrWESaWwUbtb_sherlock-and-his-skull.jpg)
Even super sleuths need a little help from their resident skull. _Alas, poor
Yorick..._
  
However, sometimes there are tools that can also give you a gut check. In our
case, we found a witness: our REST client, [Insomnia](https://insomnia.rest/).
We used Insomnia because it had the feature we needed: a GUI to interact with
our GraphQL models.

After a detailed interview with this witness, we noticed that its version of the
schema was _also_ missing the new GraphQL fields. We now had two independent
sources claiming the same, incomplete GraphQL schema. What did this mean? It
meant that there was a stale cache of some sort blocking both Insomnia and the
frontend from getting the new GraphQL fields. With that, we found out we had
violated one of our earlier rules about debugging: clearing _all_ of the caches.
Caches show up in the darndest of places! **Turns out we didn't clear our**
**backend's build cache (`sbt clean`).**

## Case Closed!

When your app is spread across more than one codebase, there are a few extra
steps to take to adapt your troubleshooting methods. This is because there are
more avenues for failure to occur, more moving parts to take care of. Hopefully,
our case will help you solve your own debugging conundrum or will inspire you to
share your own. In the mean time, Watson, let us call this mystery solved!
