{"record":{"id":"91f6cee947ee56d9","repo":"infiniflow/ragflow","slug":"main-returned-a-non-json-serializable-value","errorCode":null,"errorMessage":"main() returned a non-JSON-serializable value.","messagePattern":"main\\(\\) returned a non-JSON-serializable value\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"agent/sandbox/result_protocol.py","lineNumber":54,"sourceCode":"\n\ndef build_javascript_wrapper(code: str, args_json: str) -> str:\n    return f\"\"\"{code}\n\nconst __ragflowArgs = {args_json};\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('{RESULT_MARKER_PREFIX}' + Buffer.from(payload, 'utf8').toString('base64'));\n}})();\n\"\"\"\n\n\ndef extract_structured_result(stdout: str) -> tuple[str, dict[str, Any]]:\n    if not stdout:\n        return \"\", {}\n\n    cleaned_lines: list[str] = []\n    structured_result: dict[str, Any] = {}\n\n    for line in str(stdout).splitlines():\n        if line.startswith(RESULT_MARKER_PREFIX):\n            payload_b64 = line[len(RESULT_MARKER_PREFIX) :].strip()\n            if not payload_b64:\n                cleaned_lines.append(line)","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/infiniflow/ragflow/blob/554fb1133ac3861732235ad9c377eb5e0a770665/agent/sandbox/result_protocol.py#L36-L72","documentation":"Raised when projects.get() in validate_connector_settings raises GitlabGetError — typically HTTP 404, meaning the project path f\"{owner}/{name}\" does not exist or is invisible to the token. Wrapped as ConnectorValidationError so the UI can ask the user to fix the config.","triggerScenarios":"project_owner or project_name is misspelled, the project was renamed/transferred/deleted, a URL was pasted into the owner field, or the project is private and the token's user lacks any membership (GitLab returns 404, not 403, for hidden private projects).","commonSituations":"Copy-pasting the full HTTPS repo URL into the project owner field, renamed groups (old path 404s unless a redirect exists and redirects are disabled for API), subgroups where only the last segment was entered as owner.","solutions":["Confirm the exact path from the project page: Settings > General > Advanced > Change path, or the canonical group/project slug","For subgroups use the full nested owner, e.g. 'group/subgroup/project' → owner='group/subgroup', name='project'","Ensure the token user is a member of the project if it is private","If the project was transferred, update the connector config to the new namespace path"],"exampleFix":"# before: full URL / partial path\nconnector = GitlabConnector(project_owner=\"https://gitlab.com/acme\", project_name=\"search\")\n\n# after: exact namespace path segments\nconnector = GitlabConnector(project_owner=\"acme/infra\", project_name=\"search\")","handlingStrategy":"validation","validationCode":"import re\n\ndef parse_gitlab_project_path(url_or_path: str) -> tuple[str, str]:\n    p = url_or_path.strip().strip(\"/\")\n    p = re.sub(r\"^https?://[^/]+/\", \"\", p)\n    p = p.removesuffix(\".git\")\n    parts = p.split(\"/\")\n    if len(parts) < 2:\n        raise ValueError(\"Expected <owner>/<project>, got \" + url_or_path)\n    return \"/\".join(parts[:-1]), parts[-1]","typeGuard":null,"tryCatchPattern":"from common.data_source.exceptions import ConnectorValidationError\n\ntry:\n    connector.validate_connector_settings()\nexcept ConnectorValidationError as e:\n    if \"not found\" in str(e):\n        # re-resolve path (project may have been renamed) and retry once\n        connector.project_owner, connector.project_name = \\\n            resolve_current_path(connector.gitlab_client, connector.project_owner, connector.project_name)","preventionTips":["Normalize full URLs to owner/name before storing config","After transferring/renaming a GitLab project, update the connector config the same day","Prefer project IDs over paths in custom integrations to survive renames"],"tags":["gitlab","not-found","configuration","connector","http-404"],"backgroundTag":null,"analyzedSha":"554fb1133ac3861732235ad9c377eb5e0a770665","analyzedAt":"2026-08-15T09:20:16.380Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}