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

  1. Include relation_type in the request: 'parent' (the related work package becomes parent) or 'child' (it becomes child).
  2. Hard-refresh / clear cached frontend assets so the hierarchy form posts the shipped field set.
  3. 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

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.