# Platform Hub Gotchas and Troubleshooting Every error encountered while building the PlatformHub-Demo project, and how to fix it. ## OCL Parse Errors ### "Action Template with ID 'ActionTemplates-XX' and version v0 specified in OCL was not found" **Cause:** Process template references a step template (ActionTemplate) by ID, but step templates are space-scoped. Platform Hub operates at instance level and can't see step templates in individual spaces. **Fix:** Don't reference step templates in process template OCL. Use inline `action_type` definitions instead: ```hcl # WRONG — cross-space reference action { properties = { Octopus.Action.Template.Id = "ActionTemplates-64" Octopus.Action.Template.Version = "0" } } # RIGHT — inline action action { action_type = "Octopus.Script" properties = { Octopus.Action.RunOnServer = "true" Octopus.Action.Script.ScriptSource = "Inline" Octopus.Action.Script.Syntax = "PowerShell" Octopus.Action.Script.ScriptBody = <<-EOT Write-Host "Inline script here" EOT OctopusUseBundledTooling = "False" } worker_pool_variable = "worker_pool" } ``` ### "A step must specify a worker pool parameter" **Cause:** Every step in a process template must have a worker pool, either directly or via a variable. The template itself must define a `WorkerPool` parameter. **Fix:** Add a `worker_pool` parameter to the template and reference it from every action: ```hcl # Add this parameter to the template parameter "worker_pool" { display_settings = { Octopus.ControlType = "WorkerPool" } help_text = "Worker pool for server-side steps" label = "Worker Pool" } # On EVERY action (both RunOnServer=true and RunOnServer=false): action { action_type = "Octopus.Script" properties = { ... } worker_pool_variable = "worker_pool" # Must reference the parameter } ``` Note: `worker_pool_variable = ""` (empty string) will NOT work. It must reference an actual parameter name. ### "Name value contains invalid characters" **Cause:** Template or step names contain characters outside the allowed set. **Allowed:** Letters, numbers, periods, commas, dashes, underscores, hashes **Not allowed:** Parentheses `()`, slashes `/`, ampersands `&`, colons `:`, at-signs `@` ``` # WRONG name = "Run Security Scan (SAST/SCA)" # RIGHT name = "Run Security Scan - SAST and SCA" ``` ## API and Scripting Issues ### Step template names created as numbers instead of text **Cause:** The bash variable `GROUPS` is pre-set by bash completion scripts (contains numeric group IDs). Assigning to `GROUPS` in a script that sources other files will silently use the pre-existing value. **Fix:** Use a unique variable name that won't collide with shell builtins or completion scripts: ```bash # WRONG — GROUPS may already be set by bash completion GROUPS=("Marketplace" "Payments" "Orders") # RIGHT — use a unique name PROJECT_GROUPS=("Marketplace" "Payments" "Orders") ``` ### Action template (step template) creation: HTTP 400 with name errors **Cause:** Same name restriction as process templates. The API enforces the same character rules. ### Octopus API POST with nested command substitution loses values **Cause:** Nested `$(...)` in bash can mangle variable expansion. Avoid constructing JSON inside `$(octopus_post "/endpoint" "$(python3 ...)")`. **Fix:** Build the JSON body in a separate variable first: ```bash # WRONG — nested substitution response=$(octopus_post "/projectgroups" "$(python3 -c "..." "$name")") # RIGHT — build body first body="{\"Name\": \"$name\"}" response=$(octopus_post "/projectgroups" "$body") ``` ## Publishing and Sharing ### Templates visible in Platform Hub but not in project spaces **Cause:** Templates must be explicitly published (versioned) and shared with target spaces. Both operations are UI-only — there is no API or CLI for this. **Fix:** For each template: 1. Go to Platform Hub in the Octopus UI 2. Click the template → Publish (creates a version) 3. Click Share → select target spaces → Save ### Template changes not reflected in consuming projects **Cause:** Template versioning. Changes in Git are picked up by Platform Hub but won't affect projects until a new version is published. Projects with `version_mask = "1.X"` will auto-update on minor/patch publications. ## OCL Syntax Specifics ### Heredoc for multi-line scripts PowerShell scripts with double quotes need heredoc syntax: ```hcl Octopus.Action.Script.ScriptBody = <<-EOT $name = $OctopusParameters['Octopus.Project.Name'] Write-Host "Deploying $name" EOT ``` The `<<-EOT` variant (with dash) allows the closing `EOT` to be indented. Without the dash, `EOT` must be at column 0. ### Parameter references: single vs double braces - `#{param_name}` — standard Octopus variable substitution (most properties) - `#{{param_name}}` — escaped substitution (used in some properties like `GitRepository.FilePathFilters`) ### PowerShell variable access in scripts Inside script bodies, use `$OctopusParameters['Variable.Name']`, not `#{Variable.Name}`: ```powershell # In script body: $project = $OctopusParameters['Octopus.Project.Name'] $cloud = $OctopusParameters['cloud_target'] # NOT this (only works in OCL properties, not script text): # #{Octopus.Project.Name} ```