{"record":{"id":"81a22ae29b3d98cc","repo":"infiniflow/ragflow","slug":"main-must-return-a-value-use-null-for-an-empty-81a22a","errorCode":null,"errorMessage":"main() must return a value. Use null for an empty result.","messagePattern":"main\\(\\) must return a value\\. Use null for an empty result\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"internal/agent/sandbox/result_protocol.go","lineNumber":113,"sourceCode":"\targsB64 := base64.StdEncoding.EncodeToString([]byte(argsJSON))\n\t// Note: this string is *embedded inside* a Go raw string, but the\n\t// Go raw string and the JS source are independent languages. We\n\t// need the final JS to be valid; the doubled braces {{ }} are JS\n\t// template-literal escapes only on the JS side. We pass them\n\t// through as-is.\n\treturn code + `\n\nconst __ragflowArgsB64 = \"` + argsB64 + `\";\nconst __ragflowArgs = JSON.parse(Buffer.from(__ragflowArgsB64, 'base64').toString('utf8'));\n\n(async () => {\n  const __ragflowMain = typeof main !== 'undefined' ? main : module.exports && module.exports.main;\n  if (typeof __ragflowMain !== 'function') {\n    throw new Error('main() must be defined or exported.');\n  }\n  const output = await Promise.resolve(__ragflowMain(__ragflowArgs));\n  if (typeof output === 'undefined') {\n    throw new Error('main() must return a value. Use null for an empty result.');\n  }\n  const payload = JSON.stringify({ present: true, value: output, type: 'json' });\n  if (typeof payload === 'undefined') {\n    throw new Error('main() returned a non-JSON-serializable value.');\n  }\n  console.log('` + resultMarkerPrefix + `' + Buffer.from(payload, 'utf8').toString('base64'));\n})();\n`\n}\n\n// ExtractStructuredResult scans stdout for the marker line, decodes\n// the JSON payload after it, and returns the user-visible stdout\n// (with the marker line removed) plus the parsed structured result.\n//\n// The Python side returns `(cleaned_stdout, structured_result_dict)`.\n// On Go the dict is `map[string]any`.\n//\n// Edge cases (matching the Python implementation):","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/internal/agent/sandbox/result_protocol.go#L95-L131","documentation":"Constructor validation in GoogleDriveConnector.__init__: every indexing mode flag is falsy. The connector refuses to run a sync that would index nothing. Raised as ConnectorValidationError at construction time, before any credentials are touched.","triggerScenarios":"Instantiating GoogleDriveConnector (or saving the connector-pair config) with include_shared_drives=False, include_my_drives=False, include_files_shared_with_me=False, and empty shared_folder_urls / my_drive_emails / shared_drive_urls.","commonSituations":"UI form where all checkboxes were left unchecked, JSON config template with all flags defaulted false, a config-generation script that only emits keys when truthy.","solutions":["Enable at least one source: set include_my_drives=True for the admin's own drive, or list shared_drive_urls/shared_folder_urls/my_drive_emails","If you intended everything, include_shared_drives=True plus include_my_drives=True is the broadest combination","If the flags come from user input, validate them in the form before constructing the connector"],"exampleFix":"# before\nconnector = GoogleDriveConnector(\n    include_shared_drives=False,\n    include_my_drives=False,\n    include_files_shared_with_me=False,\n    shared_folder_urls=[],\n    my_drive_emails=[],\n)\n\n# after\nconnector = GoogleDriveConnector(\n    include_shared_drives=True,\n    include_my_drives=True,\n    include_files_shared_with_me=False,\n    shared_folder_urls=[],\n    my_drive_emails=[],\n)","handlingStrategy":"validation","validationCode":"def has_index_target(cfg: dict) -> bool:\n    return any((\n        cfg.get(\"include_shared_drives\"),\n        cfg.get(\"include_my_drives\"),\n        cfg.get(\"include_files_shared_with_me\"),\n        cfg.get(\"shared_folder_urls\"),\n        cfg.get(\"my_drive_emails\"),\n        cfg.get(\"shared_drive_urls\"),\n    ))\n\nif not has_index_target(config):\n    raise ValueError(\"Select at least one Drive source to index\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Make the UI form require at least one checkbox before submit","Default include_my_drives=True in templates so a fresh config is always valid","Run has_index_target() in config linting before the connector is constructed"],"tags":["google-drive","configuration","validation","connector"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}