opf/openproject · warning · WorkPackageHierarchyRelationsController::InvalidRelationType
Missing relation_type parameter
Error message
Missing relation_type parameter
What it means
WorkPackageHierarchyRelationsController#relation_type reads params[:relation_type] and raises InvalidRelationType('Missing relation_type parameter') when it is blank. The hierarchy tab's create action posts relation_type together with params[:work_package][:id] to express 'make X the parent/child of the current work package'; without the param the direction is undefined and the request is rejected.
Source
Thrown at app/controllers/work_package_hierarchy_relations_controller.rb:95
private
def create_hierarchy_association
if related_work_package.id.blank?
related_work_package.errors.add(:id, :blank)
return ServiceResult.failure(result: related_work_package)
end
if relation_type == "child"
set_relation(parent: @work_package, child: related_work_package)
else
set_relation(child: @work_package, parent: related_work_package)
end
end
def relation_type
type = params[:relation_type]
raise InvalidRelationType, "Missing relation_type parameter" if type.blank?
raise InvalidRelationType, "Invalid relation type: #{type}" unless type.in?([Relation::TYPE_PARENT, Relation::TYPE_CHILD])
type
end
def related_work_package
@related_work_package ||=
if params[:work_package][:id].present?
WorkPackage.visible.find(params[:work_package][:id])
else
WorkPackage.new
end
end
def set_relation(child:, parent:)
if allowed_to_set_parent?(child)
WorkPackages::UpdateService.new(
user: current_user,View on GitHub (pinned to d9742c43f3)
Solutions
- Include relation_type in the request: 'parent' (the related work package becomes parent) or 'child' (it becomes child).
- Hard-refresh / clear cached frontend assets so the hierarchy form posts the shipped field set.
- For automation, prefer the documented API endpoint for relations instead of replaying the internal form.
Example fix
# before
post work_package_hierarchy_relations_path(work_package_id: wp.id), params: { work_package: { id: other.id } }
# after
post work_package_hierarchy_relations_path(work_package_id: wp.id), params: { relation_type: 'child', work_package: { id: other.id } } Defensive patterns
Strategy: validation
Validate before calling
raise InvalidRelationType, 'relation_type required' if params[:relation_type].blank?
Type guard
def valid_relation_type?(value) value.in?([Relation::TYPE_PARENT, Relation::TYPE_CHILD]) end
Try / catch
begin
relation_type
rescue WorkPackageHierarchyRelationsController::InvalidRelationType
render json: { error: 'relation_type must be parent or child' }, status: :bad_request
end Prevention
- Make relation_type a required hidden field in the hierarchy form and assert it in request specs.
- Cache-bust frontend assets after upgrades so stale forms post the full field set.
- For API clients, use the documented relations endpoints rather than replaying internal form payloads.
When it happens
Trigger: POSTing to the work package hierarchy relations endpoint without relation_type — e.g. a custom client replaying the form, a stale JS bundle whose hidden relation_type field was renamed, or a form submission stripped of the field.
Common situations: Browser running cached/old assets after an OpenProject upgrade (field renamed or dropped from the payload); third-party automation posting to the endpoint by URL imitation; a copy-pasted form template missing the hidden input.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
AI-assisted analysis of opf/openproject@d9742c43f3 (2026-08-21).
Data as JSON: /api/errors/29373d8382f76d94.
Report an issue: GitHub.