Skip to main content
Glama
trace-parameter-validation.cjs•6.31 kB
#!/usr/bin/env node const fs = require('fs'); const path = require('path'); console.log('🔍 TRACING: Parameter Validation Flow\n'); console.log('='.repeat(80)); const serverWithAuthPath = path.join(__dirname, '../../src/server-with-auth.ts'); const serverCode = fs.readFileSync(serverWithAuthPath, 'utf8'); console.log('\n📋 STEP 1: Parameter Validation Flow (lines 608-750)\n'); console.log('-'.repeat(80)); // Extract handleApiCall function const handleApiCallMatch = serverCode.match(/private async handleApiCall\(path: string, args: any\)[^{]*\{[\s\S]*?^ \}/m); if (handleApiCallMatch) { const lines = handleApiCallMatch[0].split('\n'); console.log('Key points in parameter flow:\n'); // Find where args are processed lines.forEach((line, i) => { if (line.includes('const { username: _, ...apiArgs } = args')) { console.log(`Line ${i}: Extracting apiArgs from args (removes username)`); } if (line.includes('const queryParams: any = {}')) { console.log(`Line ${i}: Initialize queryParams`); } if (line.includes('Object.entries(apiArgs).forEach')) { console.log(`Line ${i}: Process apiArgs into queryParams`); } if (line.includes('queryParams[key] = value')) { console.log(`Line ${i}: Add parameter to queryParams`); } if (line.includes('const filterParams: Record<string, any> = {}')) { console.log(`Line ${i}: Initialize filterParams`); } if (line.includes('const regularParams: Record<string, any> = {}')) { console.log(`Line ${i}: Initialize regularParams`); } if (line.includes('Object.entries(queryParams).forEach')) { console.log(`Line ${i}: Split queryParams into filter and regular params`); } if (line.includes('QueryParamsSchema.partial().parse(regularParams)')) { console.log(`Line ${i}: ⚠️ VALIDATION - This strips unknown params!`); } if (line.includes('validatedParams = {')) { console.log(`Line ${i}: Combine validated regular params with filter params`); } }); } console.log('\n📋 STEP 2: Parameter Mapping Logic (lines 760-797)\n'); console.log('-'.repeat(80)); // Find the parameter mapping section const mappingSection = serverCode.match(/const ENDPOINTS_REQUIRING_CUSTOMER_PARAMS[\s\S]*?if \(validatedParams\.accountKey && validatedParams\.divisionId\)[\s\S]*?\} else \{[\s\S]*?\}/); if (mappingSection) { console.log('Parameter Mapping Code:\n'); const lines = mappingSection[0].split('\n').slice(0, 40); lines.forEach((line, i) => { if (line.includes('ENDPOINTS_REQUIRING_CUSTOMER_PARAMS.includes(path)')) { console.log(`Line ${i}: Check if endpoint requires customer params`); } if (line.includes('[PARAM-DEBUG]')) { console.log(`Line ${i}: Debug log - should show validated params`); } if (line.includes('if (validatedParams.accountKey && validatedParams.divisionId)')) { console.log(`Line ${i}: ⚠️ CRITICAL CHECK - needs accountKey & divisionId`); } if (line.includes('validatedParams.customer_account_key = validatedParams.accountKey')) { console.log(`Line ${i}: Map accountKey to customer_account_key`); } }); } console.log('\n📋 STEP 3: The Problem Chain\n'); console.log('-'.repeat(80)); console.log(` PROBLEM FLOW: 1. Claude sends: args = {accountKey: "24223", divisionId: "1", ...} 2. Line 608: apiArgs = {accountKey: "24223", divisionId: "1", ...} (username removed) 3. Lines 612-719: apiArgs processed into queryParams 4. Lines 721-732: queryParams split into filterParams and regularParams - regularParams = {accountKey: "24223", divisionId: "1", ...} 5. Line 749: validatedParams = QueryParamsSchema.partial().parse(regularParams) ⚠️ THIS STRIPS accountKey if not in schema! 6. Line 770: Check ENDPOINTS_REQUIRING_CUSTOMER_PARAMS 7. Line 772: Check if validatedParams.accountKey exists ❌ FAILS because accountKey was stripped at line 749! `); console.log('\n📋 STEP 4: Checking Current Schema\n'); console.log('-'.repeat(80)); const typesPath = path.join(__dirname, '../../src/types.ts'); const typesCode = fs.readFileSync(typesPath, 'utf8'); const schemaMatch = typesCode.match(/export const QueryParamsSchema = z\.object\(\{[\s\S]*?\}\);/); if (schemaMatch) { const hasAccountKey = schemaMatch[0].includes('accountKey:'); const hasDivisionId = schemaMatch[0].includes('divisionId:'); console.log(`QueryParamsSchema status:`); console.log(` ${hasAccountKey ? '✅' : '❌'} accountKey field ${hasAccountKey ? 'EXISTS' : 'MISSING'}`); console.log(` ${hasDivisionId ? '✅' : '❌'} divisionId field ${hasDivisionId ? 'EXISTS' : 'MISSING'}`); if (hasAccountKey) { const accountKeyLine = schemaMatch[0].match(/accountKey:.*$/m); console.log(` Field definition: ${accountKeyLine ? accountKeyLine[0] : 'Not found'}`); } } console.log('\n📋 STEP 5: Why [PARAM-DEBUG] Never Appears\n'); console.log('-'.repeat(80)); console.log(` The [PARAM-DEBUG] log at line 771 never appears because: 1. Line 770 checks: if (ENDPOINTS_REQUIRING_CUSTOMER_PARAMS.includes(path)) - This check PASSES for /v1/invoices/caui 2. Line 771 should log: [PARAM-DEBUG] Checking params... - This NEVER appears in logs 3. Line 772 checks: if (validatedParams.accountKey && validatedParams.divisionId) - This check MUST be failing HOWEVER: The code flow suggests line 771 should execute if line 770 passes. The fact that it doesn't appear means either: a) The code isn't reaching line 770 at all b) The compiled JavaScript is different from the TypeScript c) There's a build/deployment issue `); console.log('\n📋 STEP 6: Solution Status\n'); console.log('-'.repeat(80)); console.log(` CURRENT STATUS: 1. ✅ accountKey added to QueryParamsSchema 2. ✅ TypeScript compiled (npm run build) 3. ❌ Server still using old compiled code? NEXT STEPS: 1. Check if dist/ has latest compiled code 2. Verify the server is loading from dist/ 3. Restart server properly `); console.log('\n' + '='.repeat(80)); console.log('TRACE COMPLETE'); console.log('='.repeat(80));

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/daviddraiumbrella/invoice-monitoring'

If you have feedback or need assistance with the MCP directory API, please join our Discord server