{"record":{"id":"d3c4cc688eaba430","repo":"iflytek/astron-agent","slug":"8005-param-error","errorCode":"8005","errorMessage":"param.error","messagePattern":"param\\.error","errorType":"error_code","errorClass":"BusinessException","httpStatus":null,"severity":"error","filePath":"console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/controller/skill/SkillFileController.java","lineNumber":112,"sourceCode":"\n    @DeleteMapping\n    public ApiResult<Void> delete(@RequestParam(\"id\") Long id) {\n        skillFileService.delete(id);\n        return ApiResult.success();\n    }\n\n    @GetMapping(\"/importable\")\n    public ApiResult<List<SkillImportDto>> importable(\n            @RequestParam(value = \"keyword\", required = false) String keyword) {\n        return ApiResult.success(skillFileService.listImportableSkills(keyword));\n    }\n\n    private List<String> resolvePaths(List<String> paths, String pathsJson) {\n        if (paths != null && !paths.isEmpty()) {\n            return paths;\n        }\n        if (pathsJson == null || pathsJson.isBlank()) {\n            throw new BusinessException(ResponseEnum.PARAM_ERROR);\n        }\n        try {\n            return OBJECT_MAPPER.readValue(pathsJson, new TypeReference<List<String>>() {});\n        } catch (JsonProcessingException ex) {\n            throw new BusinessException(ResponseEnum.PARAM_ERROR);\n        }\n    }\n}\n","sourceCodeStart":94,"sourceCodeEnd":121,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/console/backend/toolkit/src/main/java/com/iflytek/astron/console/toolkit/controller/skill/SkillFileController.java#L94-L121","documentation":"PARAM_ERROR (code 8005) thrown by SkillFileController.resolvePaths when neither the direct paths parameter nor pathsJson is supplied. resolvePaths first prefers the parsed paths list; if that is absent/null/empty it requires a non-blank pathsJson string. Called by uploadDirectory, so the upload-directory endpoint rejects the request before any file work begins.","triggerScenarios":"Calling the uploadDirectory endpoint without a paths list and without pathsJson (null or whitespace-only), e.g. multipart upload where only the files were attached and no path selection was passed.","commonSituations":"Client omits the optional-looking form field entirely; frontend sends empty array instead of a JSON list; API consumers constructing multipart requests by hand forget the pathsJson part; both fields sent but paths is an empty list and pathsJson is blank.","solutions":["Send pathsJson as a valid JSON array of strings, e.g. pathsJson=\"[\\\"src/\\\",\\\"docs/readme.md\\\"]\".","Or supply the structured paths field with at least one entry.","Update the client to fall back to uploading all files (or the root) when no explicit selection exists.","On the server, consider treating an empty paths array plus missing pathsJson as 'upload everything' instead of failing, if that matches product intent."],"exampleFix":"// before\nform.append(\"file\", file); // no pathsJson part\n// after\nform.append(\"file\", file);\nform.append(\"pathsJson\", JSON.stringify([\"src/utils/\"]));","handlingStrategy":"validation","validationCode":"function validateUploadParams(paths, pathsJson) {\n  if (Array.isArray(paths) && paths.length > 0) return true;\n  if (typeof pathsJson === 'string' && pathsJson.trim().length > 0) {\n    try { return Array.isArray(JSON.parse(pathsJson)); } catch { return false; }\n  }\n  return false;\n}","typeGuard":"const hasPaths = (p) => Array.isArray(p) && p.length > 0;","tryCatchPattern":"try {\n  await api.uploadDirectory(form);\n} catch (e) {\n  if (e.code === 8005 && !form.get('pathsJson')) {\n    form.append('pathsJson', JSON.stringify(['./']));\n    await api.uploadDirectory(form);\n  } else throw e;\n}","preventionTips":["Always send pathsJson, defaulting to the directory root when nothing is selected.","Validate JSON.parse(pathsJson) before appending to the form.","Include pathsJson in the multipart request builder helper so it cannot be forgotten."],"tags":["validation","missing-parameter","skill-upload"],"backgroundTag":"missing-required-argument","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}