Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Querying allMarkdownRemark with no markdown nodes fails #2212

Closed
LegNeato opened this issue Sep 23, 2017 · 33 comments
Closed

Querying allMarkdownRemark with no markdown nodes fails #2212

LegNeato opened this issue Sep 23, 2017 · 33 comments
Labels
type: documentation An issue or pull request for improving or updating Gatsby's documentation

Comments

@LegNeato
Copy link
Contributor

If you have no markdown files in your page directory and have gatsby-transformer-remark enabled, querying for allMarkdownRemark throws an error. I would expect the query to be empty instead, as the support is there but there are no nodes.

@gre
Copy link

gre commented Sep 24, 2017

a bit on that line, I'm having hard time figuring out where is allMarkdownRemark handled in the code. at no place there is a "allMarkdownRemark" endpoint so it feels magic naming inferring? (but where?)

@LegNeato
Copy link
Contributor Author

It looks like the magic is for every node type registered (in this case MarkdownRemark) a field for all[Typename] (in this case allMarkdownRemark) is added to RootQueryType:

const typesGQL = await buildNodeTypes()

This only happens if there are nodes, hence this issue.

@nihgwu
Copy link
Contributor

nihgwu commented Sep 24, 2017

the MarkdownRemark node type will only be created when there is a markdown node, or there will be no MarkdownRemark node type at all, so you can't query allMarkdownRemark

@LegNeato
Copy link
Contributor Author

LegNeato commented Sep 24, 2017

Right, changing that behavior is what this issue is about 😄 . It was immensely confusing to install the transformer, have it in the config, yet have my queries marked as invalid. I spent a while debugging until I realized it was due to not having an existing .md file yet so there were no nodes. This also means if one were to transition off sources/transformers, a perfectly valid config can suddenly start throwing errors (like, for example if you deleted your last .md file).

While I don't think this is a huge issue, I would expect sources/transformers to register their GraphQL type and the "all" queries on source/transformer activation regardless of existing nodes.

This expectation is from the way GraphQL generally works...if you query a field that doesn't have data, you get null back rather than an error. There is a dividing line between the schema and the data in the schema, and that separation is broken when it comes to Gatsby and its plugins here.

@djm
Copy link
Contributor

djm commented Sep 24, 2017

This one caught me too; I agree it's not the largest of issues but I think it would be a move that improved the developer experience.

The core issue for me was that my first thought when it occurred was not "oh, I don't have any markdown files in that folder yet", but rather "why hasn't the plugin registered the type? There must be an issue with how I installed and configured the plugin...". And that led me on a bit of a wild goose chase.

@KyleAMathews
Copy link
Contributor

So this is interesting. I'm a bit surprised this is causing confusion. Let me try to explain my mental model for these parts of Gatsby.

At a high level this is how I see Gatsby


   +-----------+   +------------+   +----------------+
   |           |   |            |   |                |
   |  Source   +---> Transform  +--->  Infer GraphQL |
   |  Data     |   | Data       |   |  Schema        |
   |           |   |            |   |                |
   +-----------+   +------------+   +---------^------+
                                              |
                                              |
                  +-------------------+       |
                  |   GraphQL Queries+--------+
                  |                   |
                  |                   |
                  | React Web App     |
                  +-------------------+
                           |
                           v
                    Optimized Production
                    Build
                           +
                           |
                           v
                      Static Files Output

(I hope you enjoy my 5 minute ascii drawing :-D)

Source & Transformer plugins don't (generally) have anything to do with the GraphQL schema directly. They just "source" data from remote sources or "transform" data that source plugins pull in. So they don't create a schema, they create data (nodes in Gatsby-speak) which after they've finished their work, another Gatsby system comes along and infers a GraphQL schema from the nodes.

So if there's no markdown files, there's no File nodes with a mediaType of text/markdown which means gatsby-transformer-remark doesn't create an nodes of type MarkdownRemark which means there's no GraphQL types allMarkdownRemark or MarkdownRemark.

Transformer plugins don't need to know the type of nodes they're creating as often the type is only known at runtime e.g. "gatsby-source-contentful" creates nodes whose types are taken from the types of content created through the Contentful UI.

I get this is confusing as there's multiple data transformations going on and many layers of types going on as well.

I suppose a solution could be if a) a transformer plugin only creates "static" types (e.g. type names we know at code-writing time e.g. MarkdownRemark) then b) it could register with Gatsby this type name with any fields in knows for sure would be in the eventual type (generally not much).

Perhaps we just need to do a better job in docs explaining the setup so it's less surprising what's going on?

Other ideas?

@fk
Copy link
Contributor

fk commented Sep 25, 2017

(To cut down drawing time: http://asciiflow.com/ ;) Edit: Took another look and seems you used it?! :D Nevermind, sorry for the noise ppl!)

@djm
Copy link
Contributor

djm commented Sep 25, 2017

@KyleAMathews What you said makes full sense! The confusion on my part (I can't speak for LegNeato) came from making the assumption that the transformers have any say whatsoever in the graphql schema generation.

I think you're right, a documentation solution is probably enough – just telling users that transformers return just data (nodes) in the same sense source plugins do.

Edit: Perhaps if the confusion continues another solution could be that the transformers were made to report/log on the runs when they found nothing to transform; this may also help with people not realising they can remove certain transformers as they don't use them (for build perf). I can't think of a reason why you'd leave a transformer in if it wasn't transforming anything.

@KyleAMathews
Copy link
Contributor

transformers were made to report/log on the runs when they found nothing to transform

Ooo! That's a great solution. But for helping people build good mental models of Gatsby and avoiding confusion about why things aren't showing up in GraphiQL but also, yeah having lots of unused transformers would slow things down somewhat (though not a ton most likely as most plugins just do a simple if check on nodes which is very cheap).

@djm
Copy link
Contributor

djm commented Sep 25, 2017

I'm not by an editor at the mo, but I imagine it could probably happen in one place too? In whatever bit of code expects data from all the transformers.

@KyleAMathews
Copy link
Contributor

Yeah that would work. We track which plugin creates which nodes. We could add a check for plugins which implement "sourceNodes" or "onCreateNode" and check that each of these plugins created at least one node and warn if not. Wanna make the PR?

@djm
Copy link
Contributor

djm commented Sep 25, 2017

Yeah I'll take it, need to learn my away around those bits anyway!

@KyleAMathews
Copy link
Contributor

Sweet! Add the validation code here:

@djm
Copy link
Contributor

djm commented Sep 26, 2017

@KyleAMathews

Had a crack at this last night and got pretty far but I need some guidance..

Example internal output from a test project:

# Plugins that implement sourceNodes or onCreateNode.
[ 'internal-data-bridge',
  'gatsby-source-filesystem',
  'gatsby-plugin-typography',
  'gatsby-transformer-remark',
  'gatsby-transformer-sharp',
  'default-site-plugin' ]

# state.nodes are owned by:
[ 'internal-data-bridge',
  'gatsby-source-filesystem',
  'gatsby-transformer-remark' ]

# Leaving the "should warn" crowd. These use the APIs but don't own nodes.

[ 'gatsby-plugin-typography',
  'gatsby-transformer-sharp',
  'default-site-plugin' ]

Out of that final list, I believe the only one we actually want to politely warn about is gatsby-transformer-sharp, as my project had no images to find and therefore it wasn't actually used.

However, the other two pose questions:

  1. gatsby-plugin-typography implements sourceNodes but doesn't source anything.
  2. default-site-plugin - sounds like it can be ignored?

What shall we do about these two? and do you know of any others that might be edge cases?

Thanks!

@KyleAMathews
Copy link
Contributor

Sounds like the other plugins need a PR to remove the unused API implementation? Also realized that plugins can use onCreateNode to create nose fields.

@djm
Copy link
Contributor

djm commented Sep 26, 2017

@KyleAMathews You realised that yesterday so the code checks for sourceNodes and onCreateNode already :)

I'm happy making the PR to change gatsby-plugin-typography, there's a comment in there which says:

// TODO add a new API hook e.g onPreBootstrap

Do you know the status of that?

@djm
Copy link
Contributor

djm commented Sep 26, 2017

I think it'd have to be a new one, I don't see a similar API in api-node-docs, but the api-specification does mention it.

@KyleAMathews
Copy link
Contributor

Yeah, it'd be new. Lemme add it and move gatsby-plugin-typography over.

@KyleAMathews
Copy link
Contributor

@djm #2241

@Alxandr
Copy link

Alxandr commented Sep 27, 2017

You might want to allow this warning to be turned off (by the plugin). If you want to be general about it, how about something like

exports.disabledWarnings = [
  'core/no-nodes-created'
];

@djm
Copy link
Contributor

djm commented Sep 27, 2017

Yeah, that's something that can be added in time when it's definitely needed. For now, ensuring plugins don't use the incorrect APIs because there's nothing else available to them was the better option.

@djm
Copy link
Contributor

djm commented Sep 27, 2017

Update on this: near completion - just need to update the tests and add a few new cases. I don't have any time tonight so I would expect the PR more likely on Friday/over the weekend. Thanks Kyle!

@sebastienfi
Copy link
Contributor

@djm This is great, it will help a lot

@sebastienfi sebastienfi added API/Plugins type: documentation An issue or pull request for improving or updating Gatsby's documentation labels Oct 2, 2017
@djm
Copy link
Contributor

djm commented Oct 5, 2017

As ever, real life got in the way! This is coming along though:

screen shot 2017-10-05 at 09 31 15

Next step, update the tests then PR.

djm added a commit to djm/gatsby that referenced this issue Oct 22, 2017
The warning serves two purposes: a) to notify those that are
using the plugin that it hasn't created any nodes and can likely
be removed, and b) to reduce the confusion caused by a GraphQL
query for a specific node erroring as no nodes have been created
yet. See gatsbyjs#2212 for more.

As part of this work, two key changes have been made to the
redux store:

a) Each plugin now has a `nodeAPIs` key whose value retains an array
   of strings denoting the names of which Gatsby APIs the plugin
   implements.

b) At the root of the store, a new key exists named `apiToPlugins`
   has been created which stores a simple key -> val map from the
   name of a Gatsby API, to an array containing the string names
   of all plugins which implement that API.

a) is helpful when needing to know what APIs a given plugin implements
and b) is helpful when code requires a quick look up of which plugins
implement a specific API - we pay the cost once at creation time rather
than iterating through the plugin objects whenever we need to know.
KyleAMathews pushed a commit that referenced this issue Oct 24, 2017
* Add warning when node-creating plugins create no nodes

The warning serves two purposes: a) to notify those that are
using the plugin that it hasn't created any nodes and can likely
be removed, and b) to reduce the confusion caused by a GraphQL
query for a specific node erroring as no nodes have been created
yet. See #2212 for more.

As part of this work, two key changes have been made to the
redux store:

a) Each plugin now has a `nodeAPIs` key whose value retains an array
   of strings denoting the names of which Gatsby APIs the plugin
   implements.

b) At the root of the store, a new key exists named `apiToPlugins`
   has been created which stores a simple key -> val map from the
   name of a Gatsby API, to an array containing the string names
   of all plugins which implement that API.

a) is helpful when needing to know what APIs a given plugin implements
and b) is helpful when code requires a quick look up of which plugins
implement a specific API - we pay the cost once at creation time rather
than iterating through the plugin objects whenever we need to know.

* Trigger builds
@koluch
Copy link

koluch commented May 2, 2018

Hi,

Is there is any workaround for this issue? I want to make my site work fine when there are no Markdown files, but build fails with Unknown field 'allMarkdownRemark' on type 'RootQueryType'. How can I deal with it?

@nileshgulia1
Copy link

@koluch I am also experiencing this issue, did you resolved your problem?

@koluch
Copy link

koluch commented May 3, 2018

@nileshgulia1 I ended up with putting empty file in every folder I use for markdown files and then filtering them out in all the places I need them. It looks terrible, but it also fixed an issue with empty folders, because Git doesn't stores empty folders, and gatsby-source-filesystem is unable to handle non-existed folders properly :(

You can look at it here, this is the project I just started working on: https://github.com/koluch/he-he-2

@nileshgulia1
Copy link

@koluch Thanks a lot, I will look into it :)

@KyleAMathews
Copy link
Contributor

I believe this was fixed so closing

@JGallardo
Copy link

for anyone doing a google search and ends up here, your answer may be at
https://www.gatsbyjs.org/packages/gatsby-transformer-remark/

@tfaieta
Copy link

tfaieta commented Mar 19, 2019

Hi all, really loving Gatsby, but I'm running into the same issue when I'm trying to build my site. Running gatsby develop works fine but I get this error when I run gatsby build:

 Error: Cannot query field "allMarkdownRemark" on type "Query".
 GraphQL request (3:9)
 2:       {
 3:         allMarkdownRemark(
            ^
 4:           limit: 1000,

The problems started after I added gatsby-mdx and reconfigured my gatsby-config and gatsby-node files. I currently have no .MD files and only have one .MDX file.

Here's a link to the repo if you all can help me out I'd appreciate it:
https://github.com/tfaieta/tfaieta.com

@jonniebigodes
Copy link

jonniebigodes commented Mar 19, 2019

@tfaieta i've cloned your repo, installed the dependencies and issued gatsb build && gatsby serve. And i'm presented with this:
tfaieta_error

Doing a bit of digging it looks like you have installed gatsby-plugin-feed and activated it in the gatsby-config.js.
Disabling it will allow a sucessful build as you can see here:
tfaieta_build_ok

If you need that plugin, a little more of a configuration might be needed.

More on the plugin usage here

@tfaieta
Copy link

tfaieta commented Mar 19, 2019

@jonniebigodes Awesome! Thanks so much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: documentation An issue or pull request for improving or updating Gatsby's documentation
Projects
None yet
Development

No branches or pull requests