-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Issue Type
This is an issue during code generation - the Rust renderer fails when processing valid JSON Schema input containing const fields with non-string values (particularly booleans).
Context (Environment, Version, Language)
Input Format: JSON Schema (Draft 7)
Output Language: Rust
CLI, npm, or app.quicktype.io: CLI (also affects npm package quicktype-core)
Version: 23.2.6
Description
When generating Rust code from a JSON Schema that contains a const field with a boolean value, quicktype crashes with an unhelpful error message: Error: Internal error: .
This prevents code generation for schemas commonly produced by tools like zod-to-json-schema when using z.literal(true) or z.literal(false). The issue affects real-world usage where schemas need to define constant boolean values, particularly for discriminated unions or configuration objects with fixed boolean properties.
Root cause: The Rust renderer's rustType() method can return a raw boolean literal (e.g., true) instead of a valid source object. This literal value reaches serializeToStringArray() in Source.js, where it fails the switch (source.kind) check (since booleans have no .kind property), resulting in assertNever(source) being called.
Input Data
{
"type": "object",
"properties": {
"is_enabled": {
"type": "boolean",
"const": true,
"default": true
}
},
"required": ["is_enabled"]
}Real-world context: This pattern is generated by zod-to-json-schema from:
z.object({
isEnabled: z.literal(true)
})Expected Behaviour / Output
Quicktype should successfully generate Rust code, treating the const as a validation constraint. Expected output:
use serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
pub struct Test {
pub is_enabled: bool,
}Or at minimum, provide a clear error message explaining that const with non-string values is unsupported.
Current Behaviour / Output
Quicktype crashes with:
Error: Internal error: .
No additional context or stack trace is provided, making it difficult to diagnose the issue.
Debug information (when instrumenting assertNever):
assertNever called with: true
at serializeToStringArray (/node_modules/quicktype-core/dist/Source.js:182:50)Steps to Reproduce
- Create a JSON Schema file with a boolean
constvalue:
echo '{
"type": "object",
"properties": {
"is_enabled": {
"type": "boolean",
"const": true
}
},
"required": ["is_enabled"]
}' > schema.json- Run quicktype to generate Rust code:
quicktype --lang rust --src-lang schema --top-level Test schema.json- Observe the error:
Error: Internal error: .
- The same error occurs with the npm package:
const { quicktype, InputData, JSONSchemaInput, FetchingJSONSchemaStore } = require('quicktype-core');
// ... (attempting to generate from the schema above)
// Results in: Error: Internal error: .Possible Solution
Option 1: Preprocess to Remove const (Workaround - User Side)
Users can strip const values before passing to quicktype:
function normalizeSchema(schema) {
if (schema && typeof schema === 'object') {
if ('const' in schema && schema.type !== undefined) {
delete schema.const;
}
Object.keys(schema).forEach(key => {
if (typeof schema[key] === 'object') {
normalizeSchema(schema[key]);
}
});
}
return schema;
}This is acceptable since const is a validation constraint, not a type definition.
Option 2: Fix in Rust Renderer (Recommended)
Audit all type handlers in rustType() to ensure they never return raw primitive values:
// In RustRenderer.ts - ensure all handlers return valid Sourcelike types
rustType(t, withIssues = false) {
return matchType(
t,
// ... handlers should return strings, arrays, Name objects, or Source objects
(_boolType) => "bool", // ✓ Correct - returns string
// Ensure NO handler returns raw boolean/number/null literals
);
}Option 3: Add Type Guard (Defensive)
Add a safety check in splitIntoWords() in Strings.js:
function splitIntoWords(s) {
if (typeof s !== "string") {
s = String(s); // Coerce to string to prevent crash
}
// ... rest of function
}Option 4: Better Error Messages
Improve assertNever to provide actionable error messages:
function assertNever(x: never): never {
return panic(
`Internal error: Unexpected value in source tree: ${JSON.stringify(x)} (type: ${typeof x}). ` +
`This may indicate a bug in a language renderer.`
);
}Related Issues
- [BUG]: Error generating lottie scheme code #2653 - Similar issues with quicktype's handling of certain schema patterns
- This may affect other language renderers beyond Rust