theonedev/onedev · error · ExplicitException
Unable to import build spec (import project: {0}, import rev
Error message
Unable to import build spec (import project: {0}, import revision: {1}): {2} What it means
Import.getBuildSpec loads a build spec from another project/revision on behalf of the current job subject. If creating the authorization subject from the access token fails (ExplicitException), the message is wrapped as 'Unable to import build spec (import project: X, import revision: Y): <cause>'. This indicates the import itself could not authenticate, not a permission shortfall.
Source
Thrown at server-core/src/main/java/io/onedev/server/buildspec/Import.java:163
@SuppressWarnings("unused")
private static List<String> getAccessTokenSecretChoices() {
return Project.get().getHierarchyJobSecrets()
.stream().map(it->it.getName()).collect(Collectors.toList());
}
public BuildSpec getBuildSpec() {
if (buildSpec == null) {
Project project = getProject();
Subject subject;
try {
subject = JobAuthorizationContext.get().getSubject(getAccessTokenSecret());
} catch (ExplicitException e) {
var errorMessage = MessageFormat.format(
_T("Unable to import build spec (import project: {0}, import revision: {1}): {2}"),
projectPath, revision, e.getMessage());
throw new ExplicitException(errorMessage);
}
if (!subject.isPermitted(new ProjectPermission(project, new ReadCode()))
&& !project.isPermittedByLoginUser(new ReadCode())) {
String errorMessage = MessageFormat.format(
_T("Code read permission is required to import build spec (import project: {0}, import revision: {1})"),
projectPath, revision);
throw new ExplicitException(errorMessage);
}
RevCommit commit = getCommit();
try {
buildSpec = project.getBuildSpec(commit);
} catch (BuildSpecParseException e) {
String errorMessage = MessageFormat.format(
_T("Malformed build spec (import project: {0}, import revision: {1})"),
projectPath, revision);
throw new ExplicitException(errorMessage);
}View on GitHub (pinned to d44925c47c)
Solutions
- Regenerate the project access token and update the job secret used by the import
- Verify the job secret name referenced in accessTokenSecret actually exists and holds a valid token
- Check the import revision/branch still exists in the target project
- Confirm the import project path is spelled correctly and the project exists
Example fix
// before: token secret deleted/rotated accessTokenSecret: old-project-token // after accessTokenSecret: project-token # secret recreated with a live access token
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure the job secret referenced by accessTokenSecret exists and the token is not expired // (check in Project > Access Tokens before configuring the import)
Try / catch
try {
BuildSpec imported = import_.getBuildSpec();
} catch (ExplicitException e) {
// 'Unable to import build spec ...: <cause>' -> fix token/revision per cause
} Prevention
- Rotate and update access tokens used by imports promptly
- Verify secret names referenced in accessTokenSecret
- Check import project path and revision exist
- Test cross-project imports after permission changes
When it happens
Trigger: A job secret/token used for the import is invalid, expired, revoked, or empty; JobAuthorizationContext.get().getSubject(accessTokenSecret) throws ExplicitException during getBuildSpec().
Common situations: Referencing another project's build spec with a job token that lacks access; rotating project access tokens without updating the job secret; typos in the secret reference so the token resolves to nothing; importing from a revision that no longer exists.
Related errors
- Code read permission is required to import build spec (impor
- Malformed build spec (import project: {0}, import revision:
- Build spec not defined (import project: {0}, import revision
- Error validating imported build spec (import project: %s, im
- A valid agent token is expected
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/0cedd8d6b29285e4.
Report an issue: GitHub.