Skip to content

file loader produces incorrect json schema #13536

@gnosticdev

Description

@gnosticdev

Astro Info

Astro                    v5.1.8
Node                     v22.13.1
System                   macOS (arm64)
Package Manager          bun
Output                   server
Adapter                  @astrojs/vercel
Integrations             @astrojs/tailwind
                         @astrojs/sitemap
                         astro-typed-links

If this issue only occurs in one browser, which browser is a problem?

No response

Describe the Bug

When using the file loader, or a custom loader that results in the creation of a single json file, the resulting json schema is incorrectly typed as a 'object' instead of 'array'.

From the docs:

The file() loader creates entries from a single file that contains an array of objects with a unique id field, or an object with IDs as keys and entries as values.
  1. If you pass in a zod object as schema, the json schema definition is of type 'object'. This then makes the json file have invalid type inference because it expects an 'object', while it is an array of objects.
  2. If you pass in a zod array of objects, the json schema is an 'array', but the parser fails bc it is parsing each object in the array.

Example 1: using object schema

// src/content.config.ts
const dogsCollection = defineCollection({
    loader: file('src/data/dogs.json'),
    schema: z.object({
        id: z.string(),
        name: z.string()
    })
})
// src/data/dogs.json
[{
  "id": 1,
  "name": "yorkie"
  }, {
  "id": 2,
  "name": "lab"
}]
// .astro/collections/dogs.schema.json
{
  "$ref": "#/definitions/dogs",
  "definitions": {
    "dogs": {
      "type": "object",
      "properties": {
        "id": {
          "type": "number"
        },
        "name": {
          "type": "string"
        },
        "$schema": {
          "type": "string"
        }
      },
      "required": [
        "id",
        "name"
      ],
      "additionalProperties": false
    }
  },
  "$schema": "http://json-schema.org/draft-07/schema#"
}

Resulting Error (VSCode)

Image

Example 2: using array schema

// src/content.config.ts
const dogsCollection = defineCollection({
    loader: file('src/data/dogs.json'),
    schema: z.array(
        z.object({
            id: z.number(),
            name: z.string(),
        }),
    ),
})
⚡ bun run sync
$ astro sync --force
12:39:40 [content] Syncing content
[InvalidContentEntryDataError] dogs → 1 data does not match collection schema.
Expected type `"array"`, received `"object"`
  Hint:
    See https://docs.astro.build/en/guides/content-collections/ for more information on content schemas.
  Error reference:
    https://docs.astro.build/en/reference/errors/invalid-content-entry-data-error/
  Location:
    /Users/divinelight/code/clients/provision-rpm/src/data/dogs.json:0:0
  Stack trace:
    at getEntryDataAndImages (file:///Users/divinelight/code/clients/provision-rpm/node_modules/astro/dist/content/utils.js:163:26)
    at async syncData (/Users/divinelight/code/clients/provision-rpm/node_modules/astro/dist/content/loaders/file.js:49:28)
    at async Promise.all (index 4)
    at async file:///Users/divinelight/code/clients/provision-rpm/node_modules/p-queue/dist/index.js:230:36
error: script "sync" exited with code 1

What's the expected result?

If we pass in an object as schema, the loader should recognize that the file contains an array of this object type, and produce an json schema for an array of objects.

{
  "$ref": "#/definitions/dogs",
  "definitions": {
    "dogs": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number"
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name"
        ],
        "additionalProperties": false
      }
    }
  },
  "$schema": "http://json-schema.org/draft-07/schema#"
}

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-wuk59bem?file=.vscode%2Fsettings.json

Participation

  • I am willing to submit a pull request for this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    - P3: minor bugAn edge case that only affects very specific usage (priority)feat: content collectionsRelated to the Content Collections feature (scope)requires refactorBug, may take longer as fixing either requires refactors, breaking changes, or considering tradeoffs

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions