Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions integrations/.nango/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -58521,6 +58521,17 @@
},
"email": {
"type": "string"
},
"user_fields": {
"type": "object",
"additionalProperties": {
"anyOf": [
{},
{
"not": {}
}
]
}
}
Comment on lines +58525 to 58535
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, check if the file exists and get context around the specified lines
head -n 58540 integrations/.nango/schema.json | tail -n 20

Repository: NangoHQ/integration-templates

Length of output: 202


🏁 Script executed:

# Check the file header to verify if it's auto-generated
head -n 10 integrations/.nango/schema.json

Repository: NangoHQ/integration-templates

Length of output: 202


🏁 Script executed:

# Search for TypeScript models.ts to find user_fields definition
find . -name "models.ts" -type f | head -5

Repository: NangoHQ/integration-templates

Length of output: 202


🌐 Web query:

JSON Schema empty schema {} vs {"not": {}} anyOf semantics

💡 Result:

Short answer

  • {} (empty object schema) places no constraints — every instance validates. [1][2]
  • {"not": {}} negates the empty schema (which always passes), so it always fails (no instance validates). [2][3]

anyOf behavior

  • anyOf succeeds if at least one subschema validates.
    • anyOf: [ {} ] accepts every instance (because {} accepts everything). [1][2]
    • anyOf: [ { "not": {} } ] rejects every instance (because that single subschema always fails). [2][3]
  • Mixed examples:
    • anyOf: [ { "type": "string" }, {} ] is equivalent to {} (accepts all instances).
    • anyOf: [ { "type": "string" }, { "not": {} } ] is equivalent to { "type": "string" } (the always-failing subschema has no effect).

Notes / references

  • Formal spec: empty schema = no properties = accepts all; boolean schemas true/false semantics. [1]
  • Explanation of "not" (negation) and examples showing {"not": {}} is always false. [2][3]

Sources
[1] JSON Schema specification (empty schema / boolean schemas).
[2] JSON Schema blog / tutorial (empty schema and "not, empty object" example).
[3] learnjsonschema: "not" keyword explanation.


🌐 Web query:

Nango v0.69.14 schema generation auto-generated files

💡 Result:

Short answer: In Nango (including v0.69.14) the CLI's schema generation creates two auto-generated files under the .nango directory: .nango/schema.ts (TypeScript models) and .nango/schema.json (JSON Schema used for validation). These files are safe to version with your repo and are used by the CLI/runtime for automatic input/output validation. [1][2]

Sources

  • Nango docs — Data validation (explains .nango/schema.ts and .nango/schema.json). [1]
  • Nango GitHub — release v0.69.14 (release exists). [2]

Simplify the contradictory JSON schema pattern for user_fields.

The anyOf pattern combining {} and {"not": {}} is semantically invalid. The empty schema {} matches any value, while {"not": {}} matches nothing (since it negates the always-permissive empty schema). This makes the anyOf condition unsatisfiable.

Simplify this to:

"user_fields": {
  "type": "object",
  "additionalProperties": {}
}

Or, if you need to be explicit about allowing any type within the object properties, use true:

"user_fields": {
  "type": "object",
  "additionalProperties": true
}

This file is auto-generated by Nango v0.69.14. The contradictory schema pattern indicates a bug in Nango's schema generation logic that should be reported or fixed upstream.

🤖 Prompt for AI Agents
In integrations/.nango/schema.json around lines 58525 to 58535, the user_fields
schema uses an invalid anyOf combining "{}" (matches everything) and '{"not":
{}}' (matches nothing), making the condition contradictory; replace the anyOf
block with a simple additionalProperties schema that allows any value — either
an empty object for permissive properties or the boolean true to explicitly
allow any type — to produce a valid, non-contradictory JSON Schema.

},
"required": [
Expand Down
71 changes: 47 additions & 24 deletions integrations/zendesk/mocks/users/User/batchSave.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,138 +3,161 @@
"id": "32763192893073",
"firstName": "The",
"lastName": "Customer",
"email": "customer@example.com"
"email": "customer@example.com",
"user_fields": {}
},
{
"id": "32763206658065",
"firstName": "Kelvin",
"lastName": "Wari",
"email": "hassanwari254@gmail.com"
"email": "hassanwari254@gmail.com",
"user_fields": {}
},
{
"id": "32763235076113",
"firstName": "Zhang",
"lastName": "Wei",
"email": "zhang.weixu@example.com"
"email": "zhang.weixu@example.com",
"user_fields": {}
},
{
"id": "32763235217681",
"firstName": "Ingrid",
"lastName": "Van",
"email": "ingrid.vandijk@example.com"
"email": "ingrid.vandijk@example.com",
"user_fields": {}
},
{
"id": "32763266879633",
"firstName": "Soobin",
"lastName": "Do",
"email": "soobin.do@example.com"
"email": "soobin.do@example.com",
"user_fields": {}
},
{
"id": "32763282580241",
"firstName": "Customer",
"lastName": "",
"email": "example@zendesk.com"
"email": "example@zendesk.com",
"user_fields": {}
},
{
"id": "32768199515537",
"firstName": "Roger",
"lastName": "Wilco",
"email": null
"email": null,
"user_fields": {}
},
{
"id": "32768693470737",
"firstName": "Roger",
"lastName": "Wilco",
"email": null
"email": null,
"user_fields": {}
},
{
"id": "32768722488209",
"firstName": "Roger",
"lastName": "Wilco",
"email": null
"email": null,
"user_fields": {}
},
{
"id": "32768749121553",
"firstName": "tests",
"lastName": "in",
"email": "tco@test.com"
"email": "tco@test.com",
"user_fields": {}
},
{
"id": "32777971122577",
"firstName": "John",
"lastName": "Doe",
"email": "johndoe@example.com"
"email": "johndoe@example.com",
"user_fields": {}
},
{
"id": "32778022853009",
"firstName": "Johns",
"lastName": "Doe",
"email": "johndoes@example.com"
"email": "johndoes@example.com",
"user_fields": {}
},
{
"id": "32778051354129",
"firstName": "Johns",
"lastName": "Doe",
"email": "johndoes@examples.com"
"email": "johndoes@examples.com",
"user_fields": {}
},
{
"id": "32778088066961",
"firstName": "Johns",
"lastName": "Does",
"email": "johndoesss@example.com"
"email": "johndoesss@example.com",
"user_fields": {}
},
{
"id": "32778096357905",
"firstName": "Johnsw",
"lastName": "Does",
"email": "johndoesssww@example.com"
"email": "johndoesssww@example.com",
"user_fields": {}
},
{
"id": "32778150390161",
"firstName": "John",
"lastName": "Doe",
"email": "customer1@example.com"
"email": "customer1@example.com",
"user_fields": {}
},
{
"id": "32778203764369",
"firstName": "James",
"lastName": "Doe",
"email": "jamescustomer@example.com"
"email": "jamescustomer@example.com",
"user_fields": {}
},
{
"id": "32888998590865",
"firstName": "Jane",
"lastName": "Doe",
"email": "janedoe@example.com"
"email": "janedoe@example.com",
"user_fields": {}
},
{
"id": "32889172187409",
"firstName": "Sample",
"lastName": "User",
"email": "sampleuser-1@gmail.com"
"email": "sampleuser-1@gmail.com",
"user_fields": {}
},
{
"id": "32889564879505",
"firstName": "Sample",
"lastName": "User2",
"email": "sampleuser-2@gmail.com"
"email": "sampleuser-2@gmail.com",
"user_fields": {}
},
{
"id": "32889653118481",
"firstName": "Sample",
"lastName": "User2",
"email": "sampleuser-2@gmail.comp"
"email": "sampleuser-2@gmail.comp",
"user_fields": {}
},
{
"id": "32890003697937",
"firstName": "Sample",
"lastName": "User2999",
"email": "sampleuser-3@gmail.com"
"email": "sampleuser-3@gmail.com",
"user_fields": {}
},
{
"id": "32981016448017",
"firstName": "Sample",
"lastName": "User2",
"email": "sampleuser-43@gmail.com"
"email": "sampleuser-43@gmail.com",
"user_fields": {}
}
]
]
3 changes: 2 additions & 1 deletion integrations/zendesk/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ export const User = z.object({
id: z.string(),
firstName: z.string(),
lastName: z.string(),
email: z.string()
email: z.string(),
user_fields: z.record(z.string(), z.any()).optional()
});

export type User = z.infer<typeof User>;
Expand Down
3 changes: 2 additions & 1 deletion integrations/zendesk/syncs/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ const sync = createSync({
id: zUser.id.toString(),
firstName: firstName || '',
lastName: lastName || '',
email: zUser.email
email: zUser.email,
user_fields: zUser.user_fields
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! You need to add this user_fields property and its shape to the User object in the models

};
});

Expand Down
2 changes: 1 addition & 1 deletion integrations/zendesk/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ export interface ZendeskUser {
suspended: boolean;
default_group_id: number;
report_csv: boolean;
user_fields: Record<string, any>;
user_fields?: Record<string, any>;
}

interface ZendeskAttachmet {
Expand Down
Loading
Loading