OtterMind/Chat2DB · error · Error

Data validation failed: ${error.message}

Error message

Data validation failed: ${error.message}

What it means

validateData throws when a Zod schema parse fails, wrapping the ZodError message into a generic Error. It is a thin wrapper around schema.parse that converts ZodError (which has its own structure with issues array) into a standard Error with a concatenated message string. The underlying schema (DataSourceTreeSchema / FilterInputSchema) expects datasourceId to be a number and hiddenTreeNodeIds to be an array of strings.

Source

Thrown at chat2db-community-client/src/database/validation.ts:22

export const DataSourceTreeSchema = z.object({
  datasourceId: z.number(),
  hiddenTreeNodeIds: z.array(z.string()),
});

// Schema used to validate input parameters
export const FilterInputSchema = z.object({
  datasourceId: z.number(),
  hiddenTreeNodeIds: z.array(z.string()).optional(),
});

export type DataSourceTreeSchemaInput = z.infer<typeof FilterInputSchema>;

export const validateData = <T>(data: T, schema: z.ZodType<T>): void => {
  try {
    schema.parse(data);
  } catch (error) {
    if (error instanceof z.ZodError) {
      throw new Error(`Data validation failed: ${error.message}`);
    }
    throw error;
  }
};

View on GitHub (pinned to 5ee1e990e7)

Solutions

  1. Inspect error.message — it contains the Zod issues with the path and expected type.
  2. Coerce datasourceId to Number before validation if the backend sends a string.
  3. Update the Zod schema to match the actual API contract (e.g., z.coerce.number(), .nullable(), .default([])).
  4. Use safeParse instead if you want to handle failures without throwing.

Example fix

// before
export const DataSourceTreeSchema = z.object({
  datasourceId: z.number(),
  hiddenTreeNodeIds: z.array(z.string()),
});

// after — coerce and default to handle backend variance
export const DataSourceTreeSchema = z.object({
  datasourceId: z.coerce.number(),
  hiddenTreeNodeIds: z.array(z.string()).default([]),
});
Defensive patterns

Strategy: validation

Validate before calling

function isDataSourceTreeInput(data: unknown): data is { datasourceId: number; hiddenTreeNodeIds?: string[] } {
  return (
    typeof data === 'object' && data !== null &&
    typeof (data as any).datasourceId === 'number' &&
    (Array.isArray((data as any).hiddenTreeNodeIds)
      ? (data as any).hiddenTreeNodeIds.every((x: unknown) => typeof x === 'string')
      : (data as any).hiddenTreeNodeIds === undefined)
  );
}

if (!isDataSourceTreeInput(data)) {
  throw new Error('Invalid datasource tree input');
}

Type guard

function isDataSourceTreeInput(data: unknown): data is { datasourceId: number; hiddenTreeNodeIds?: string[] } {
  return (
    !!data && typeof data === 'object' &&
    typeof (data as any).datasourceId === 'number'
  );
}

Try / catch

const result = FilterInputSchema.safeParse(data);
if (!result.success) {
  console.error('Validation issues:', result.error.issues);
  // handle each issue path/message
} else {
  // use result.data
}

Prevention

When it happens

Trigger: Calling validateData(data, DataSourceTreeSchema) where data.datasourceId is missing, null, a string, or undefined. Or data.hiddenTreeNodeIds is not an array of strings (e.g., null, or array of numbers). Calling with FilterInputSchema and omitting datasourceId.

Common situations: Backend returns datasourceId as a string instead of number (JSON parsing). hiddenTreeNodeIds is null when the backend omits it for the non-optional schema. API contract change where a field type changed but the frontend schema was not updated.

Related errors


AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14). Data as JSON: /api/errors/b3c801313698d4b9. Report an issue: GitHub.