const fs = require('fs'); const content = fs.readFileSync('temp/rich-outline-fail_57_1779015509994.txt', 'utf-8'); const marker = '========== AI εŽŸε§‹ε“εΊ” '; const markerIdx = content.indexOf(marker); const headerEndIdx = content.indexOf(' ==========', markerIdx); const aiStart = content.indexOf('\n', headerEndIdx) + 1; const aiEnd = content.indexOf('\n\n', aiStart); const aiResponse = content.substring(aiStart, aiEnd); console.log('AI response length:', aiResponse.length); // Check for issues with opening braces let inString = false; let escapeNext = false; let braceLevel = 0; let issues = []; for (let i = 0; i < aiResponse.length; i++) { const ch = aiResponse[i]; if (escapeNext) { escapeNext = false; continue; } if (ch === '\\') { escapeNext = true; continue; } if (ch === '"') { inString = !inString; continue; } if (!inString) { if (ch === '{') { braceLevel++; // Check the next non-space character let j = i + 1; while (j < aiResponse.length && aiResponse[j] === ' ') j++; if (j < aiResponse.length && aiResponse[j] !== '"' && aiResponse[j] !== '}') { issues.push({pos: i, char: ch, nextChar: aiResponse[j], context: aiResponse.substring(Math.max(0,i-20), i+30)}); } } else if (ch === '}') { braceLevel--; } } } console.log('\nOpening brace issues found:', issues.length); if (issues.length > 0) { issues.slice(0, 5).forEach(issue => { console.log(' pos', issue.pos, ': char', JSON.stringify(issue.char), 'next', JSON.stringify(issue.nextChar)); console.log(' context:', JSON.stringify(issue.context)); }); } // Check last 200 chars of position 1624 const before1624 = aiResponse.substring(0, 1624); console.log('\nLast 200 chars before position 1624:'); console.log(JSON.stringify(before1624.substring(before1624.length - 200))); // Check if the problem is an UNESCAPED comma or something within a string value // that ends up looking like a property delimiter console.log('\n=== Checking for string value issues ==='); // Find all unescaped [ or { that appear inside string values inString = false; escapeNext = false; let stringIssues = []; let lastStringStart = -1; let stringContent = ''; for (let i = 0; i < aiResponse.length; i++) { const ch = aiResponse[i]; if (escapeNext) { escapeNext = false; stringContent += ch; continue; } if (ch === '\\') { escapeNext = true; stringContent += ch; continue; } if (ch === '"') { if (inString) { // End of string inString = false; } else { // Start of string inString = true; lastStringStart = i; stringContent = ''; } continue; } if (inString) { stringContent += ch; // Check if there's a ,{ pattern inside the string that might cause issues if (stringContent.endsWith(',{') || stringContent.endsWith(',{')) { stringIssues.push({pos: i, content: stringContent.slice(-20)}); } } } console.log('Potential string value issues:', stringIssues.length); if (stringIssues.length > 0) { stringIssues.slice(0, 3).forEach(si => { console.log(' pos', si.pos, 'content ending:', JSON.stringify(si.content)); }); } // The error at position 1624 is a "{" when inString should be false // Let me check if maybe there's an issue with how I'm reading the file // Let's just try to print the actual bytes at position 1624 in the original file console.log('\n=== Re-reading file for byte-level check ==='); const fileContent = fs.readFileSync('temp/rich-outline-fail_57_1779015509994.txt'); const fileContentStr = fileContent.toString('utf-8'); const aiStartIdx = fileContentStr.indexOf(marker); const headerEndIdxStr = fileContentStr.indexOf(' ==========', aiStartIdx); const aiStartOffset = fileContentStr.indexOf('\n', headerEndIdxStr) + 1; const aiEndOffset = fileContentStr.indexOf('\n\n', aiStartOffset); const aiFromFile = fileContentStr.substring(aiStartOffset, aiEndOffset); console.log('aiFromFile length:', aiFromFile.length); console.log('Position 1624 from file:', JSON.stringify(aiFromFile[1624]), 'code:', aiFromFile.charCodeAt(1624)); // Try parsing aiFromFile try { JSON.parse(aiFromFile); console.log('aiFromFile: SUCCESS'); } catch(e) { console.log('aiFromFile: FAILED -', e.message.substring(0, 80)); const pos = parseInt(e.message.match(/position (\d+)/)?.[1] || '0'); if (pos === 1624) { console.log('Same error at position 1624 - issue is in the data itself'); } }