semaphoreui/semaphore · error

is required for owner

Error message

%s is required for owner %q

What it means

When storing an object owned by another entity (project, environment, task, etc.), the corresponding owner ID field must be set. If the required ID value is nil, the store returns '<field> is required for owner "<owner>"', naming the missing field (e.g. task_id) and the owner kind.

Solutions

  1. Set the required owner ID field (e.g. TaskID) before saving the object
  2. Only set Owner when you actually have the corresponding ID; otherwise leave Owner empty
  3. Validate the request payload for the owner ID before mapping it into the store object

Example fix

// before
o := db.ObjectProps{Owner: "task"}
store.Create(o)
// after
o := db.ObjectProps{Owner: "task", TaskID: &task.ID}
store.Create(o)
Defensive patterns

Strategy: validation

Validate before calling

func validateOwner(o *db.ObjectProps) error {
    switch o.Owner {
    case "task":
        if o.TaskID == nil {
            return errors.New("task_id is required for owner 'task'")
        }
    }
    return nil
}

Try / catch

if err := store.Create(o); err != nil {
    if strings.Contains(err.Error(), "is required for owner") {
        return fmt.Errorf("payload missing owner id: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Creating/storing an owned object via the ObjectProps-based APIs with an Owner such as 'task' but leaving the corresponding ID field (e.g. TaskID) nil.

Common situations: Programmatic resource creation that sets Owner but forgets the ID; struct literals built dynamically where optional fields were skipped; API payloads missing the owner ID field.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of semaphoreui/semaphore@1774ccb71a (2026-09-07). Data as JSON: /api/errors/2d7cb5e004e8342d. Report an issue: GitHub.

Appendix: source

Thrown at db/Store.go:361

		return nil
	}

	var value *int
	var name string

	switch o.Owner {
	case AccessKeyVariable, AccessKeyEnvironment:
		value, name = o.EnvironmentID, "environment_id"
	case AccessKeySecretStorage:
		value, name = o.StorageID, "storage_id"
	case AccessKeyTaskSecret:
		value, name = o.TaskID, "task_id"
	default:
		return nil
	}

	if value == nil {
		return fmt.Errorf("%s is required for owner %q", name, o.Owner)
	}

	return nil
}

// AccessKeyManager handles access key-related operations
type AccessKeyManager interface {
	GetAccessKey(projectID int, accessKeyID int) (AccessKey, error)
	GetAccessKeyRefs(projectID int, accessKeyID int) (ObjectReferrers, error)
	GetAccessKeys(projectID int, options GetAccessKeyOptions, params RetrieveQueryParams) ([]AccessKey, error)
	UpdateAccessKey(accessKey AccessKey) error
	CreateAccessKey(accessKey AccessKey) (AccessKey, error)
	DeleteAccessKey(projectID int, accessKeyID int) error
	// GetTaskAccessKey returns the AccessKeyTaskSecret-owned key of a task
	// (survey secret variables), or ErrNotFound when the task has none.
	GetTaskAccessKey(projectID int, taskID int) (AccessKey, error)
	// DeleteTaskAccessKeys removes all AccessKeyTaskSecret-owned keys of a task.
	// Deleting for a task without such keys is not an error.

View on GitHub (pinned to 1774ccb71a)