alibaba/nacos · error · NacosApiException
20004
20004
Error message
Base version not found: {basedOnVersion} What it means
Thrown by PromptOperationServiceImpl.createDraft when forking (basedOnVersion supplied) but resourceManager.findVersion returns null for that version — the base version to fork from does not exist for this prompt. Reported as RESOURCE_NOT_FOUND (HTTP 404). Note: listing shows code=20004 which is the RESOURCE_NOT_FOUND numeric code.
Source
Thrown at ai/src/main/java/com/alibaba/nacos/ai/service/prompt/PromptOperationServiceImpl.java:180
AiResourceTraceService.logSuccess(RESOURCE_TYPE_PROMPT, promptKey, version,
AiResourceTraceService.OP_CREATE_DRAFT, VisibilityHelper.resolveCurrentIdentity(),
VisibilityHelper.resolveClientIp());
return version;
}
// Existing prompt
VisibilityHelper.checkWritableResource(meta);
PromptVersionInfoPojo info = requireVersionInfo(meta);
ResourceVersionInfo resourceInfo = toResourceVersionInfo(info);
AiResourceManager.ensureNoWorkingVersion(resourceInfo, "create draft");
if (StringUtils.isNotBlank(basedOnVersion)) {
// Fork from existing version
AiResourceVersion baseRow = resourceManager.findVersion(namespaceId, promptKey,
RESOURCE_TYPE_PROMPT, basedOnVersion);
if (baseRow == null) {
throw new NacosApiException(NacosException.NOT_FOUND, ErrorCode.RESOURCE_NOT_FOUND,
"Base version not found: " + basedOnVersion);
}
PromptVersionInfo baseContent = loadPromptFromStorage(namespaceId, promptKey,
basedOnVersion, baseRow.getStorage());
String newVersion = StringUtils.isBlank(targetVersion)
? incrementVersion(basedOnVersion) : targetVersion;
validateVersion(newVersion);
checkVersionNotExists(namespaceId, promptKey, newVersion);
String storageJson = writePromptToStorage(namespaceId, promptKey, newVersion,
baseContent.getTemplate(), baseContent.getVariables(), null);
String currentUser = VisibilityHelper.resolveCurrentIdentity();
resourceManager.insertVersionRow(namespaceId, promptKey, RESOURCE_TYPE_PROMPT,
StringUtils.isBlank(currentUser) ? DEFAULT_AUTHOR : currentUser,
VERSION_STATUS_DRAFT, newVersion, commitMsg, storageJson);
resourceManager.markEditingVersionCas(namespaceId, meta, resourceInfo, newVersion,View on GitHub (pinned to 9b989acdf1)
Solutions
- List the prompt's versions and use an existing one as basedOnVersion.
- Verify the version string matches exactly (case, no whitespace).
- If the base was deleted, fork from the latest remaining published version.
- If you want a fresh draft from scratch, omit basedOnVersion and supply a template instead.
Example fix
// before promptService.createDraft(ns, key, "9.9.9", null, ...); // base not found // after List<String> versions = listPromptVersions(ns, key); String base = versions.isEmpty() ? null : versions.get(versions.size() - 1); promptService.createDraft(ns, key, base, null, ...);
Defensive patterns
Strategy: validation
Validate before calling
// Confirm basedOnVersion exists before forking
if (basedOnVersion != null && !basedOnVersion.isBlank()) {
List<String> versions = promptService.listVersions(ns, promptKey);
if (!versions.contains(basedOnVersion)) {
throw new IllegalArgumentException("Unknown base version: " + basedOnVersion);
}
}
promptService.createDraft(ns, promptKey, basedOn, target, template, vars, msg, desc, tags); Try / catch
try {
promptService.createDraft(ns, key, basedOn, target, template, vars, msg, desc, tags);
} catch (NacosApiException e) {
if (e.getErrCode() == ErrorCode.RESOURCE_NOT_FOUND.getCode()
&& e.getErrMsg().contains("Base version not found")) {
// fork from the latest existing version instead
basedOn = listVersions(ns, key).stream().reduce((a, b) -> b).orElse(null);
promptService.createDraft(ns, key, basedOn, target, template, vars, msg, desc, tags);
} else { throw e; }
} Prevention
- Populate basedOnVersion only from server-returned version lists.
- Refresh the version list before forking to avoid stale references.
- Scope version lookups by namespaceId.
When it happens
Trigger: createDraft with a basedOnVersion that was never published, was deleted, or is mistyped for the given promptKey.
Common situations: Stale version reference after a rollback; cross-environment copy where the source version is absent; typo in basedOnVersion; race where the version was deleted between a list and the fork.
Related errors
AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14).
Data as JSON: /api/errors/38085beb148a9325.
Report an issue: GitHub.