Skip to content

Instantly share code, notes, and snippets.

@axl89
Created September 18, 2025 10:00
Show Gist options
  • Select an option

  • Save axl89/525d9cbb15031f2f0e22aea406b6ac5b to your computer and use it in GitHub Desktop.

Select an option

Save axl89/525d9cbb15031f2f0e22aea406b6ac5b to your computer and use it in GitHub Desktop.
Mistral Typescript client bug with complex types
import { z } from 'zod';
import { Mistral } from '@mistralai/mistralai';
import dotenv from 'dotenv';
dotenv.config();
async function testSchemaStep(schema, name) {
try {
const client = new Mistral({
apiKey: process.env.MISTRAL_API_KEY
});
const response = await client.chat.parse({
model: "mistral-large-latest",
messages: [{ role: "user", content: `Create sample data for ${name}` }],
responseFormat: schema,
temperature: 0,
});
console.log(`βœ… ${name}: WORKS`);
return true;
} catch (error) {
console.log(`❌ ${name}: FAILS - ${error.message}`);
return false;
}
}
async function findBreakingPoint() {
console.log('πŸ” Finding exactly where your schema breaks...\n');
// Step 1: Basic citation (this works from our tests)
const Citation = z.object({
pages: z.array(z.number()),
quote: z.string().optional(),
});
await testSchemaStep(Citation, 'Basic Citation');
// Step 2: Text with citations
const TextWithCitations = z.object({
text: z.string(),
citations: z.array(Citation).optional(),
});
await testSchemaStep(TextWithCitations, 'Text with Citations');
// Step 3: Rule item
const RuleItem = z.object({
label: z.string(),
detail: z.string().optional(),
citations: z.array(Citation).optional(),
});
await testSchemaStep(RuleItem, 'Rule Item');
// Step 4: Money object
const Money = z.object({
amount: z.number(),
currency: z.string().default("EUR"),
});
await testSchemaStep(Money, 'Money');
// Step 5: Eligibility with arrays
const Eligibility = z.object({
company_requirements: z.array(RuleItem).optional(),
project_requirements: z.array(RuleItem).optional(),
financial_requirements: z.array(RuleItem).optional(),
});
await testSchemaStep(Eligibility, 'Eligibility');
// Step 6: Financing
const Financing = z.object({
instrument_type: z.enum(["GRANT", "LOAN", "PARTICIPATIVE_LOAN", "MIXED"]),
grant_coverage_pct: z.number().optional(),
grant_amount_cap: Money.optional(),
loan_coverage_pct: z.number().optional(),
min_financing: Money.optional(),
max_financing: Money.optional(),
loan_duration_months: z.number().optional(),
interest_type: z.enum(["FIXED", "VARIABLE", "PROFIT_LINKED"]).optional(),
interest_rate_pct: z.number().optional(),
notes: z.string().optional(),
citations: z.array(Citation).optional(),
});
await testSchemaStep(Financing, 'Financing');
// Step 7: Minimal version of your full schema
const MinimalFull = z.object({
schema_version: z.literal("1.0"),
line_name: z.string(),
overview: TextWithCitations,
instrument_type: z.enum(["GRANT", "LOAN", "PARTICIPATIVE_LOAN", "MIXED"]),
});
await testSchemaStep(MinimalFull, 'Minimal Full Schema');
// Step 8: Add eligibility
const WithEligibility = z.object({
schema_version: z.literal("1.0"),
line_name: z.string(),
overview: TextWithCitations,
instrument_type: z.enum(["GRANT", "LOAN", "PARTICIPATIVE_LOAN", "MIXED"]),
eligibility: Eligibility.optional(),
});
await testSchemaStep(WithEligibility, 'With Eligibility');
// Step 9: Add financing (this might be the breaking point)
const WithFinancing = z.object({
schema_version: z.literal("1.0"),
line_name: z.string(),
overview: TextWithCitations,
instrument_type: z.enum(["GRANT", "LOAN", "PARTICIPATIVE_LOAN", "MIXED"]),
eligibility: Eligibility.optional(),
financing: Financing.optional(),
});
await testSchemaStep(WithFinancing, 'With Financing');
// Step 10: Your exact full schema
const FullSchema = z.object({
schema_version: z.literal("1.0"),
line_name: z.string(),
organizer: z.string().optional(),
jurisdiction: z.string().optional(),
overview: TextWithCitations,
instrument_type: z.enum(["GRANT", "LOAN", "PARTICIPATIVE_LOAN", "MIXED"]),
eligibility: Eligibility.optional(),
financing: Financing.optional(),
notes: z.string().optional(),
});
await testSchemaStep(FullSchema, 'Full Schema (Exact Copy)');
console.log('\n🎯 This will show us exactly where the complexity breaks!');
}
findBreakingPoint().catch(console.error);
@axl89
Copy link
Author

axl89 commented Sep 18, 2025

The bug is:

➜  project git:(main) βœ— nvm use 20 && node test-step-by-step.js
Now using node v20.19.5 (npm v10.8.2)
πŸ” Finding exactly where your schema breaks...

βœ… Basic Citation: WORKS
βœ… Text with Citations: WORKS
βœ… Rule Item: WORKS
βœ… Money: WORKS
❌ Eligibility: FAILS - API error occurred: Status 400
Body: {"object":"error","message":"Did not find definition for reference `items`","type":"invalid_request_json_schema","param":null,"code":"3300"}
❌ Financing: FAILS - API error occurred: Status 400
Body: {"object":"error","message":"Did not find definition for reference `grant_amount_cap`","type":"invalid_request_json_schema","param":null,"code":"3300"}
βœ… Minimal Full Schema: WORKS
❌ With Eligibility: FAILS - API error occurred: Status 400
Body: {"object":"error","message":"Did not find definition for reference `items`","type":"invalid_request_json_schema","param":null,"code":"3300"}
❌ With Financing: FAILS - API error occurred: Status 400
Body: {"object":"error","message":"Did not find definition for reference `items`","type":"invalid_request_json_schema","param":null,"code":"3300"}
❌ Full Schema (Exact Copy): FAILS - API error occurred: Status 400
Body: {"object":"error","message":"Did not find definition for reference `items`","type":"invalid_request_json_schema","param":null,"code":"3300"}

🎯 This will show us exactly where the complexity breaks!

Package JSON for reference:

{
  "name": "example-graph",
  "version": "0.0.1",
  "description": "A starter template for creating a LangGraph workflow.",
  "packageManager": "yarn@1.22.22",
  "main": "my_app/graph.ts",
  "author": "Your Name",
  "license": "MIT",
  "private": true,
  "type": "module",
  "scripts": {
    "build": "tsc",
    "clean": "rm -rf dist",
    "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --testPathPattern=\\.test\\.ts$ --testPathIgnorePatterns=\\.int\\.test\\.ts$",
    "test:int": "node --experimental-vm-modules node_modules/jest/bin/jest.js --testPathPattern=\\.int\\.test\\.ts$",
    "format": "prettier --write .",
    "lint": "eslint src",
    "format:check": "prettier --check .",
    "lint:langgraph-json": "node scripts/checkLanggraphPaths.js",
    "lint:all": "yarn lint & yarn lint:langgraph-json & yarn format:check",
    "test:all": "yarn test && yarn test:int && yarn lint:langgraph"
  },
  "dependencies": {
    "@langchain/core": "^0.3.76",
    "@langchain/langgraph": "^0.4.9",
    "@langchain/mistralai": "^0.2.1",
    "@langchain/openai": "^0.6.12",
    "@mistralai/mistralai": "^1.10.0",
    "langsmith": "^0.3.68",
    "openai": "^5.20.3",
    "zod": "^3.23.8",
    "zod-to-json-schema": "^3.24.1"
  },
  "devDependencies": {
    "@eslint/eslintrc": "^3.1.0",
    "@eslint/js": "^9.9.1",
    "@langchain/langgraph-cli": "^0.0.66",
    "@tsconfig/recommended": "^1.0.7",
    "@types/jest": "^29.5.0",
    "@typescript-eslint/eslint-plugin": "^5.59.8",
    "@typescript-eslint/parser": "^5.59.8",
    "dotenv": "^16.4.5",
    "eslint": "^8.41.0",
    "eslint-config-prettier": "^8.8.0",
    "eslint-plugin-import": "^2.27.5",
    "eslint-plugin-no-instanceof": "^1.0.1",
    "eslint-plugin-prettier": "^4.2.1",
    "jest": "^29.7.0",
    "prettier": "^3.3.3",
    "ts-jest": "^29.1.0",
    "typescript": "^5.3.3"
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment