theonedev/onedev · error · ExplicitException

Undefined property: ${propertyName}

Error message

Undefined property: ${propertyName}

What it means

JobVariableInterpolator resolves @property:name@ (or 'properties:name') references by first checking the current property values, then walking the project hierarchy's job properties (getHierarchyJobProperties). If no property with that name exists anywhere in the hierarchy, it throws ExplicitException 'Undefined property'. This enforces that only defined project/job properties can be interpolated.

Source

Thrown at server-core/src/main/java/io/onedev/server/util/interpolative/JobVariableInterpolator.java:86

					}
				}
				throw new ExplicitException("Undefined param: " + paramName);
			} else if (t.startsWith(PREFIX_PROPERTY) || t.startsWith("properties:")) {
				String propertyName;
				if (t.startsWith(PREFIX_PROPERTY))
					propertyName = t.substring(PREFIX_PROPERTY.length());
				else
					propertyName = t.substring("properties:".length());

				JobProperty property = build.getSpec().getPropertyMap().get(propertyName);
				if (property != null) {
					return property.getValue();
				} else {
					for (var projectProperty : build.getProject().getHierarchyJobProperties()) {
						if (projectProperty.getName().equals(propertyName))
							return projectProperty.getValue();
					}
					throw new ExplicitException("Undefined property: " + propertyName);
				}
			} else if (t.startsWith(PREFIX_SECRET) || t.startsWith("secrets:")) {
				String secretName;
				if (t.startsWith(PREFIX_SECRET))
					secretName = t.substring(PREFIX_SECRET.length());
				else
					secretName = t.substring("secrets:".length());
				return build.getJobAuthorizationContext().getSecretValue(secretName);
			} else if (t.startsWith(PREFIX_SCRIPT) || t.startsWith("scripts:")) {
				String scriptName;
				if (t.startsWith(PREFIX_SCRIPT))
					scriptName = t.substring(PREFIX_SCRIPT.length());
				else
					scriptName = t.substring("scripts:".length());

				Map<String, Object> context = new HashMap<>();
				context.put("build", build);
				Object result = GroovyUtils.evalScriptByName(scriptName, context);

View on GitHub (pinned to d44925c47c)

Solutions

  1. Define the property with that exact name on the project (or a parent project) that owns the job.
  2. Fix the property name in the expression to match an existing property definition.
  3. Remove the @property:...@ reference if the property is obsolete.
  4. Verify name and casing against getHierarchyJobProperties (the lookup is exact-match).

Example fix

// before (property 'registry_url' not defined on this project)
String expr = "@property:registry_url@/myapp";
// after: add property registry_url on the project, or reference an existing one
String expr = "@property:dockerRegistry@/myapp";
Defensive patterns

Strategy: validation

Validate before calling

boolean propertyDefined(Project project, String name) {
    return project.getHierarchyJobProperties().stream()
        .anyMatch(pp -> pp.getName().equals(name));
}

Try / catch

try {
    value = interpolate("@property:foo@");
} catch (ExplicitException e) {
    if (e.getMessage().startsWith("Undefined property")) {
        value = defaultValue; // or prompt to define the property
    } else throw e;
}

Prevention

When it happens

Trigger: An expression like '@property:myProp@' where no property named 'myProp' is defined on the current job's project or any project in its hierarchy — e.g. the property was deleted, defined on an unrelated project, or misspelled.

Common situations: Defining the property on a sibling project instead of an ancestor; deleting a project property still referenced by job configurations; case-sensitivity/typo mismatches in property names; copying job configs between projects that lack the property.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/062f11fd10de09a3. Report an issue: GitHub.