How I Fixed: Error: The number of path segments is not divisible by 2 in “”

Perhaps “how I fixed” is a poor title for this one. I don’t think I fixed it, but I found a workaround.

Here’s the gist of the problem:

docker run --rm \
		--env-file /path/to/my/terraform/azure/.env \
		-v /path/to/my/terraform/azure:/workspace \
		-w /workspace \
		my-custom/terraform:local \
		apply --auto-approve
╷
│ Error: The number of path segments is not divisible by 2 in ""
│ 
│   with azurerm_linux_virtual_machine.christest,
│   on create-instance.tf line 1, in resource "azurerm_linux_virtual_machine" "christest":
│    1: resource "azurerm_linux_virtual_machine" "christest" {
│ 
╵
╷
│ Error: The number of path segments is not divisible by 2 in ""
│ 
│   with azurerm_linux_virtual_machine.christest,
│   on create-instance.tf line 1, in resource "azurerm_linux_virtual_machine" "christest":
│    1: resource "azurerm_linux_virtual_machine" "christest" {
│ 
╵
╷
│ Error: The number of path segments is not divisible by 2 in ""
│ 
│   with azurerm_linux_virtual_machine.christest,
│   on create-instance.tf line 1, in resource "azurerm_linux_virtual_machine" "christest":
│    1: resource "azurerm_linux_virtual_machine" "christest" {
│ 

Some extra info that may / may not be helpful in this particular instance is that I wanted to run Terraform through Docker. In order to work with Azure command line (az) I had to bake that into the Dockerfile

FROM hashicorp/terraform:1.0.10

RUN \
  apk update && \
  apk add bash py-pip && \
  apk add --virtual=build gcc libffi-dev musl-dev openssl-dev python3-dev make && \
  python3 -m pip install --upgrade pip && \
  python3 -m pip install azure-cli && \
  apk del --purge build

To build the Dockerfile I then do a docker build -t my-custom/terraform:local . which is where that custom Docker image is coming from above. Names changed to protect the innocent.

Anyway, I have a bunch of files in this project mainly to split things out for the sake of my sanity. Where Terraform seemed to die was with this first file:

resource "azurerm_linux_virtual_machine" "christest" {
  name                            = "${var.owner}-vm"
  resource_group_name             = azurerm_resource_group.christest.name
  location                        = azurerm_resource_group.christest.location
  size                            = var.instance_size
  admin_username                  = "adminuser"
  admin_password                  = "abadpassword"
  disable_password_authentication = false
  network_interface_ids = [
    azurerm_network_interface.christest.id,
  ]

  source_image_id = var.source_image_id

  os_disk {
    storage_account_type = "Standard_LRS"
    caching              = "ReadWrite"
  }
}

By and large, I’d simply copied this from the docs and then tried to be a smart arse and turned some of the things into variables.

Here’s where things got confusing.

As above, the Terraform output complains that:

Error: The number of path segments is not divisible by 2 in ""

This error repeats three times.

Hmmm. Three times… well, wait. Don’t I have three variables here, right at the top? Probably them, right?

No. No matter what I did – and it got to the point where I hardcoded them – the error remained. If it remained when they were just plain old strings, there was no way it was these lines causing the problem.

So, I dutifully copy / pasted the entire Azure config in from the docs, and lo-and-behold, that worked first time. D’oh.

What else had I changed?

source_image_id = var.source_image_id

And the associated variable I’d created:

# az vm image list --output table

variable "source_image_id" {
  description = "The ID of the Image which this Virtual Machine should be created from"
  type        = string
  default     = "Canonical:UbuntuServer:18.04-LTS:latest"
}

That’s not how it’s set in the example from the docs. Here’s what they have:

  source_image_reference {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "18.04-LTS"
    version   = "latest"
  }

Annoyingly, I didn’t even need this set as a variable. I’d just tried to be that aforementioned smart arse, which had bitten me on said arse.

There isn’t an example in the docs of how to use source_image_id, I’d just guessed. Wrongly, it seems.

And why I say I haven’t fixed this is I still don’t know the right format to use here. I just know that by using source_image_reference then the error goes away. Good enough for me.

How I Fixed: Mono location is not specified in settings correctly and can not be discovered automatically. Please check Mono settings under File | Settings | Build, Execution, Deployment | Toolset and Build

For everything in life there is a JetBrains product. Right? Right.

So for C# development when using Linux, I wanted to use JetBrains Rider.

All went well, I needed to upgrade to Ubuntu 21.04 to install dotnet, but surprisingly, that all went off without a hitch. No full OS reinstall needed! Miracles do happen. I should put on a lottery ticket.

Anyway, by and large my dotnet’ing then went well enough. At least for the stuff I was doing (tutorials and exercism exercises, mainly). But then one day (today, just now) I wanted to debug something, and when I tried I got the message:

Mono location is not specified in settings correctly and can not be discovered automatically. Please check Mono settings under File | Settings | Build, Execution, Deployment | Toolset and Build

Being a dotnet newb, I didn’t fully understand why / what Mono is. As best I recalled from some previous work with Unity, Mono was a kind of editor that worked cross platform? Is that even the same thing? Who the heck knows.

Anyway, after a few failed attempts at fixing this following anonymous folk on StackOverflow (copy > paste > run > curse!), I discovered the answer. Very simple. Bit of a face palm moment:

sudo apt install mono-devel

So, err, yeah. Won’t work if it’s not installed.

Easy peasy.

How I Fixed: docker: Error response from daemon: Decoding seccomp profile failed: json: cannot unmarshal array into Go value of type seccomp.Seccomp.

Another day, another cryptic error message from Docker.

Right, so here’s what I was trying to do.

Blindly following the Playwright docs for getting a Playwright Docker container up and running, I first created a new file, seccomp_profile.json inside the current directory. The location of this directory is irrelevant, just the file needs to live in the directory from which you (or I) run the command.

And the command is directly lifted from the 1.14 docs:

docker run -it --rm --ipc=host --user pwuser --security-opt seccomp=seccomp_profile.json mcr.microsoft.com/playwright:focal /bin/bash

When doing this, I got the error above, but for clarity (and for SEO purposes) here it is again:

docker: Error response from daemon: Decoding seccomp profile failed: json: cannot unmarshal array into Go value of type seccomp.Seccomp.

This tells us that whilst the file was read, the contents are somehow wrong.

I’m just going to skip straight to the fix here, as I tried a few things and got lucky. Sadly, I don’t know jack about Golang, but I loosely understand the error above as saying hey, Chris, that JSON file doesn’t decode into a format my program is expecting.

Here’s what MS give:

[
  {
    "comment": "Allow create user namespaces",
    "names": [
      "clone",
      "setns",
      "unshare"
    ],
    "action": "SCMP_ACT_ALLOW",
    "args": [],
    "includes": {},
    "excludes": {}
  }
]

And here’s what it needs to be:

  {
    "comment": "Allow create user namespaces",
    "names": [
      "clone",
      "setns",
      "unshare"
    ],
    "action": "SCMP_ACT_ALLOW",
    "args": [],
    "includes": {},
    "excludes": {}
  }

Or, in short, not an array. Just a single object.

Why the docs have it that way, I don’t know.

Go figure.

Arf arf.

How I Fixed: unknown flag: –project-name in GitHub Actions

Bit of an obscure one this, and given that I received absolutely no Google results, I’m guessing may be of little help to … well, anyone. But perhaps this is the price one pays for being an early adopter.

The Problem

I created a GitHub actions workflow that ran a Makefile command. It looked something like this:

---
name: E2E Tests

on: [push, pull_request]

jobs:
    test:
        runs-on: ubuntu-latest

        steps:
            - uses: actions/checkout@v2

            - name: make install
              run: make install

            - name: make serve
              run: make serve

Excuse the crappy steps, I was / am still kinda experimenting with this workflow.

Anyway, what we really care about (and where the problem actually lies) is in what the make install command represents:

serve:
	docker compose \
		-p my_project_name_here \
		 --remove-orphans && \
		docker compose up --remove-orphans
.PHONY: serve

Don’t be put off if you don’t use / understand Makefile‘s, but if you don’t, they are pretty useful. Other solutions exist, yadda yadda.

Keen eyed readers will have spotted something potentially curious:

docker compose ...

Not:

docker-compose ...

Yeah, so I got this from a little info at the end of my local command line output:

➜  my-project git:(e2e-tests-setup) docker-compose
Define and run multi-container applications with Docker.

Usage:
  docker-compose [-f <arg>...] [--profile <name>...] [options] [--] [COMMAND] [ARGS...]
  docker-compose -h|--help

 ...

Docker Compose is now in the Docker CLI, try `docker compose`

(Excuse the formatting, WP does its own thing)

See that line at the very end. Why not try the new stuff, right? Who doesn’t love the shiny.

But herein lies the problem. Note, even the official docs aren’t (yet) consistent in what format they use.

The Solution

The solution to this problem is super simple.

Use docker-compose for your GitHub actions commands.

The problem arises because GitHub actions thinks I’m trying to run docker commands, and must be using an older version of the Docker CLI.

Locally:

docker -v
Docker version 20.10.7, build f0df350

GitHub Actions:

Run docker -v
Docker version 20.10.7+azure, build f0df35096d5f5e6b559b42c7fde6c65a2909f7c5

Anyway, my fix was to change the Makefile command to use docker-compose instead of docker compose:

serve:
	docker-compose \
		-p my_project_name_here \
		 --remove-orphans && \
		docker-compose up --remove-orphans
.PHONY: serve

How I Fixed: Kotlin Spring Boot Auto Reload in IntelliJ IDEA

Coming from a world of JavaScript (and prior, PHP), I am used to my code automatically updating as soon as I save my project. Lately I’ve been playing around with Kotlin, and as of today, Kotlin with Spring Boot inside Intellij IDEA.

And what bugged the heck out of me was that the project needed a manual restart each and every time I made a change.

Now, I found several tutorials that explain how to fix this, but none of them actually solved my problem. So here’s what I had to do – and sadly it’s not absolutely perfect, but it is 95% of the way there.

As ever, if you know a better way, please do share by leaving a comment. Thanks!

The Stuff Everyone Else Says

Google for this problem and there’s a set of steps you will find in almost every result:

  1. Add the Spring Boot Dev Tools to your project dependencies. I am using Grade, so here’s what I had to do:
dependencies {
   implementation("org.springframework.boot:spring-boot-devtools")
   ... other stuff
}
  1. File > Settings… > Build, Execution, Deployment > Compiler > tick Build project automatically
  2. Press SHIFT+CTRL+A (Win/*nix) or Command+SHIFT+A (Mac) to open a pop-up windows, type registry
  3. Find and enabled this option compiler.automake.allow.when.app.running

So far, so good. All those steps are taken from here.

However, after doing this, my project didn’t start auto-restarting whenever I made a change.

The Extra Step

What I had to do was edit my project’s run/debug configuration:

And then in there, select to “update classes and resources” on update, and frame deactivation:

It’s slap bang in the middle, if you are missing it…

Once I’d done this, the Spring Boot app did begin to restart when I made a change to my, admittedly, very simple application.

I had this:

package demo

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController

@SpringBootApplication
class DemoApplication

fun main(args: Array<String>) {
   runApplication<DemoApplication>(*args)
}

data class Message(val id: String?, val text: String)

@RestController
class MessageResource {
   @GetMapping
   fun index(): List<Message> = listOf(
         Message("1", "Hello"),
         Message("2", "Dag"),
         Message("3", "Goedenavond"),
   )

}

And then I could add a fourth, fifth, sixth, etc entry to the list:

@GetMapping
fun index(): List<Message> = listOf(
      Message("1", "Hello"),
      Message("2", "Dag"),
      Message("3", "Goedenavond"),
      Message("4", "Chris"),
      Message("5", "Code Review Videos"),
)

And so why I say it’s not perfect is that yes, it does rebuild the project, but only when IntelliJ loses focus.

In other words, I need to manually switch to e.g. Postman and only then does the project rebuild. I find this a little strange, but it’s good enough.

My concerns would be that if you have a large Kotlin / Java project, this compilation step may take a while, and so that’s why this isn’t a thing by default(?).

Who knows. It’s fine for my “hello world” tier abilities. And also my PC is ridiculously OP anyway, so 🤷 right?