Skip to content

cmd/cue: eval error of conflicting values combining .json with .cue files #1479

Closed
@slewiskelly

Description

What version of CUE are you using (cue version)?

Originally v0.4.1 darwin/amd64, but tested all versions back to a known working version (v0.3.2 darwin/amd64).

Specifically, this seems to be a regression since #9366, which was released in the 0.4.0-alpha.1 release.

Does this issue reproduce with the latest release?

Yes.

What did you do?

Given this CUE file:

import (
        "list"
)

#Check: {
        ok: true
        ...
}

#Role: "EM" | "IC" | "TL"

#Team: {
        members: [Username=string]: #TeamMember & {email: string | *"\(Username)@acme.com"}
}

#TeamMember: {
        email: string & !=""
        role:  [...#Role] | *["IC"]
}

checks: [string]: #Check

team: #Team

checks: {
        enoughMembers: {
                ok: len(team.members) >= 1
        }

        hasManager: {
                ok: len([ for m in team.members if list.Contains(m.role, "EM") {m}]) >= 1
        }
}

and data from this JSON file:

{
  "team": {
    "members": {
      "alice": {
        "email": "[email protected]",
        "role": ["EM"]
      },
      "bob": {
        "role": ["TL"]
      },
      "clyde": {}
    }
  }
}

I ran:

cue eval team.cue team.json -e checks

What did you expect to see?

I expect this to evaluate to:

enoughMembers: {
    ok: true
}
hasManager: {
    ok: true
}

As the number of team members correctly evaluates to three:

$ cue eval team.cue team.json -e 'len(team.members)'
3

as does the length of managers, to one:

$ cue eval team.cue team.json -e 'len([for m in team.members if list.Contains(m.role, "EM") {m}])'
1

Both of which are obviously >= 1.

What did you see instead?

When unifying the result of this expression with #Check.ok (true), a conflict occurs:

checks.enoughMembers.ok: conflicting values true and false:
    ./team.cue:6:6
    ./team.cue:21:19
    ./team.cue:27:7
checks.hasManager.ok: conflicting values true and false:
    ./team.cue:6:6
    ./team.cue:21:19
    ./team.cue:31:7

I found that this works:

checks: {
	enoughMembers: {
		ok: len(team.members) >= 0
	}

	hasManager: {
		ok: len([ for m in team.members if list.Contains(m.role, "EM") {m}]) >= 0
	}
}

It is expected that one of the following evaluates correctly, given that >= 0 works, but neither of these work:

checks: {
	enoughMembers: {
		ok: len(team.members) == 0
	}

	hasManager: {
		ok: len([ for m in team.members if list.Contains(m.role, "EM") {m}]) == 0
	}
}
checks: {
	enoughMembers: {
		ok: len(team.members) > 0
	}

	hasManager: {
		ok: len([ for m in team.members if list.Contains(m.role, "EM") {m}]) > 0
	}
}

The same check, written differently, works as expected:

checks: {
	enoughMembers: {
		ok: or([ for m in team.members {true}])
	}

	hasManager: {
		ok: or([ for m in team.members {list.Contains(m.role, "EM")}])
	}
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions