Skip to content

Zod 3 upload error path throws on bigint schemas, so the unsupported-type error becomes a generic CSV error #1647

Open

Description

@joshunrau

On the Zod 3 CSV upload path, the error branch for an unsupported field schema can itself throw. Zod3.getZodTypeName builds its log line with JSON.stringify(schema), which throws TypeError: Do not know how to serialize a BigInt for any schema that holds a bigint, such as z.literal(1n). The intended UploadError ("Unexpected Error") is never thrown. When downloading a template, the raw TypeError reaches the page's catch, which drops the description. When uploading a CSV, the user sees the generic "Error parsing CSV" instead of an error that names the column. The effect is small, since bigint fields are rare in form instruments, but this error path should not depend on the schema being JSON-serializable.

Where

apps/web/src/utils/upload.ts:288-291 (Zod3.getZodTypeName):

if (!isZodTypeDef(def)) {
  console.error(`Cannot parse ZodType from schema: ${JSON.stringify(schema)}`);
  throw new UploadError({ en: 'Unexpected Error', fr: 'Erreur inattendue' });
}

Reproduce

Use a Zod 3 form instrument with validationSchema: z.object({ big: z.literal(1n) }). Upload:

subjectID,date,big
subject1,2024-01-01,1
  • Actual: "Error parsing CSV". The console shows the TypeError from JSON.stringify.
  • Expected: "Unexpected Error at column name: 'big' and row number '1'", which is what any other unsupported type, such as z.literal('a'), produces.

Tests

apps/web/src/utils/__tests__/upload.test.ts, test 'should fall back to a generic error when an unsupported field schema cannot be serialized for logging' (under Zod3 › processInstrumentCSV). When fixing, rename it and change the expected rejection from 'Error parsing CSV' to "Unexpected Error at column name: 'big' and row number '1'".

Suggested fix

Pass the schema object straight to console.error instead of stringifying it, or log only def.typeName. Better still, throw UnexpectedZodTypeError.forTypeName(def.typeName), so the user is told which type is unsupported.

Found while raising unit test coverage in #1632.

Activity

  1. added
    BugType: existing behavior is wrong
    Priority: LowNice to have, cosmetic or speculative
    Difficulty: LowIsolated change, about 2 hours or less
    Area: Webapps/web (clinician-facing React SPA)
    Good First IssueWell-scoped, low-risk and self-contained; a good entry point for a new contributor
    on Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area: Webapps/web (clinician-facing React SPA)BugType: existing behavior is wrongDifficulty: LowIsolated change, about 2 hours or lessGood First IssueWell-scoped, low-risk and self-contained; a good entry point for a new contributorPriority: LowNice to have, cosmetic or speculative

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions