From 0761c05b6272bf98d5a9fc1fba6950856417cb8d Mon Sep 17 00:00:00 2001 From: Floke Date: Sat, 3 Jan 2026 13:44:18 +0000 Subject: [PATCH] Fix: Resolved E2BIG error by switching to file-based payload passing for large requests (images) --- gtm-architect/server.cjs | 25 +++++++++++++++++++++---- gtm_architect_orchestrator.py | 23 +++++++++++++++++------ 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/gtm-architect/server.cjs b/gtm-architect/server.cjs index bc3fb24c..72376a7c 100644 --- a/gtm-architect/server.cjs +++ b/gtm-architect/server.cjs @@ -48,15 +48,25 @@ app.post('/api/run', (req, res) => { return res.status(400).json({ error: 'Mode is required' }); } - // Convert payload to a JSON string and then to a Base64 string to ensure safe command line passing - const payloadString = JSON.stringify(payload); - const payloadBase64 = Buffer.from(payloadString).toString('base64'); + // E2BIG FIX: Write payload to a temporary file instead of passing via command line args + const tmpDir = path.join(__dirname, 'tmp'); + if (!fs.existsSync(tmpDir)) { + fs.mkdirSync(tmpDir); + } + const payloadFilePath = path.join(tmpDir, `payload_${Date.now()}_${Math.random().toString(36).substring(7)}.json`); + + try { + fs.writeFileSync(payloadFilePath, JSON.stringify(payload)); + } catch (err) { + console.error("Failed to write payload file:", err); + return res.status(500).json({ error: "Failed to process request payload." }); + } const pythonScriptPath = path.join(__dirname, 'gtm_architect_orchestrator.py'); const pythonProcess = spawn('python3', [ pythonScriptPath, '--mode', mode, - '--payload_base64', payloadBase64 + '--payload_file', payloadFilePath // Use file path instead of base64 string ]); let stdoutData = ''; @@ -76,6 +86,13 @@ app.post('/api/run', (req, res) => { }); pythonProcess.on('close', (code) => { + // Cleanup temp file + try { + if (fs.existsSync(payloadFilePath)) fs.unlinkSync(payloadFilePath); + } catch (e) { + console.error("Failed to delete temp payload file:", e); + } + if (code !== 0) { console.error(`Python script exited with code ${code}`); console.error('Stderr:', stderrData); diff --git a/gtm_architect_orchestrator.py b/gtm_architect_orchestrator.py index 0de48223..042b10e5 100644 --- a/gtm_architect_orchestrator.py +++ b/gtm_architect_orchestrator.py @@ -379,17 +379,28 @@ def main(): """ parser = argparse.ArgumentParser(description="GTM Architect Orchestrator") parser.add_argument("--mode", required=True, help="The execution mode (e.g., phase1, phase2).") - parser.add_argument("--payload_base64", required=True, help="The Base64 encoded JSON payload.") + parser.add_argument("--payload_base64", help="The Base64 encoded JSON payload (deprecated, use payload_file).") + parser.add_argument("--payload_file", help="Path to a JSON file containing the payload (preferred).") args = parser.parse_args() + payload = {} try: - payload_str = base64.b64decode(args.payload_base64).decode('utf-8') - payload = json.loads(payload_str) - except (json.JSONDecodeError, base64.binascii.Error) as e: - logging.error(f"Failed to decode payload: {e}") + if args.payload_file: + if not os.path.exists(args.payload_file): + raise FileNotFoundError(f"Payload file not found: {args.payload_file}") + with open(args.payload_file, 'r', encoding='utf-8') as f: + payload = json.load(f) + elif args.payload_base64: + payload_str = base64.b64decode(args.payload_base64).decode('utf-8') + payload = json.loads(payload_str) + else: + raise ValueError("No payload provided (neither --payload_file nor --payload_base64).") + + except (json.JSONDecodeError, base64.binascii.Error, ValueError, FileNotFoundError) as e: + logging.error(f"Failed to load payload: {e}") # Print error as JSON to stdout for the server to catch - print(json.dumps({"error": "Invalid payload format.", "details": str(e)})) + print(json.dumps({"error": "Invalid payload.", "details": str(e)})) sys.exit(1) # Function mapping to dynamically call the correct phase