Change:
executables = listOf str; outputsToInstall = listOf str; position = str; <del> available = bool; </del> <ins> available = unspecified; </ins> isBuildPythonPackage = platforms; schedulingPriority = int; isFcitxEngine = bool;

Discussion:
Since from , evaluating my configuration of nixos-unstable is giving: I'm still encountering it at the latest nixos-unstable, I have not further narrowed down whether it is something specific to my configuration that triggers the issue, but here is the snippet from my that might be most relevant: Disabling makes the problem go away, but I kinda don't want to ;). Please run and paste the result.
That's a weird one. Because I did not know about until now, it is undocumented and used exactly once in the entire nixpkgs. Have you explicitly set that option to true in your configuration? The pull request I did enabled by default, so it might be the cause nevertheless. Could you please confirm that the commit before works fine? Also, can you please try to minimize the package set which causes this? I think this is an issue with the check-meta evaluation, and it only surfaces through transitive dependencies.
Yes I did - TBH I don't remember what exactly prompted it, but it sounds like a good idea at least ;) Confirmed Will-do (hopefully tonight)
I'm not maintaining this, just making sure documentation is readable and self-consistent. I do not vouch for its correctness (this should be maintainers' responsibility).
I can reproduce this with at least the following packages: chromium, adwaita-icon-theme, gtk3, tracker, libsoup, sysprof. I'm not sure what to make out of this. I don't really understand the option and how it works. Initially my assumption was that this is a failure that should be reproducible even if if you just find the right package, but that might not be the case. CC
I notice that the failure is only reproducible when both and are enabled. I guess this is because the dependency tree has some cyclic dependency somehow, but due to laziness it is only exposed through the combination of both options. Since the only relevant changed the default of , I have the strong supposition that both options never truly worked together. how did you find that option, and what exactly do you need it for? As far as I can see, it is used nowhere in nixpkgs and also undocumented. I am therefore inclined to remove it.

Pinging users of this option based on
indeed with "infinite recursion" errors yeah :disappointed: Please don't without at least offering a way to get equivalent functionality. You can find some discussion on if you want some context. It's my opinion that should be the default behaviour, and I believe it only isn't due to performance reasons. I do also consider it a bit of a longstanding nixpkgs bug that this isn't the default behaviour, because if a package transiently depends on something unfree or , evaluating it will an error even though . If this is removed, may be the only remaining option and I consider that to be a poor hacky solution.
Thanks for the input. I think I'm slowly starting to better understand the situation. defaulted to false, which I considered a long-standing issue and thus changed it. defaults to false, and we probably want to have that changed too Due to the default values, both have almost never been tested together, and thus never worked. When enabling both, it produces some infinitive recursion error on some packages. I tried debugging it but then ran My tolerance of undocumented options is limited. If we want to keep it in, it must be properly documented.
Okay, I finally understand the interaction between both options: forces the evaluation of , and if then recursively for all dependencies forces the evaluation of in order to check its type There are packages like which have the following line . With the usual laziness this is not a problem, but the recursive forcing of attributes results in an infinite recursion: libsysprof- requires (forced through ) goes through all dependences (because of ), including Infinite recursion on There is no good way to forbid such recursive trickeries in nixpkgs, therefore and are mutually incompatible. However, it is possible to build a custom check that does the same recursive decent externally: Please let me know if this suits your use case.
For now, the quickest fix might be to make the two options mutually exclusive; it could disable if recursive is on, or assert/throw if they're both on? I'd be happy to see it documented, regardless of whether it becomes enabled by default or not! This sounds wrong, I don't see why this can't be fixed. There can't be a true recursive dependency here between the two derivations.

A simple fix to this seems like it would just be to ignore , so it can't be set via (it already can't be; if that's really what you wanted, you need to use or something) - it doesn't even really need to be type-checked if it's only set by . You could even consider this to be poor form, and encourage the following instead: While it can be done, it feels like a bit of a hack? Efficiency also seems a bit complicated compared to the free thunks you get from having also the concerns stated in seem relevant to mention here.
I think that creating a custom helper function that recursively checks all attributes of a derivation would be the cleanest solution. is pretty efficient because the code walking the tree and checking for cycles is written in C++ (people have already build the same thing in Nix, and it was both ugly and slow). As a bonus, that solution would make the option obsolete (I generally consider less options and thus less complexity as a win). I am not convinced of your approach of simply removing the attribute from the type check, because it might clash with future attempts to tighten the type checking of (e.g. using a module system).
While I agree that this feature could use more discussion about a future design, I see nothing wrong with fixing an obvious bug in the existing logic. I still do think that recursive checking should be default behaviour, and probably tied to rather than being a separate option to begin with? The thing to realise here is that setting is nonsensical; it gets overwritten by , so the value is effectively ignored. So... -checking a value that never sees the light of day outside of that internal check is silly. anything, there should be a warning that was set to anything, since doing so is ineffectual and probably a mistake. The attr's existence should probably fail a check - its value doesn't even need to be typechecked to do this. This sentiment might apply to some of the other attrs as well. just ties back into the idea that the pattern is lazy and assigns values that one doesn't even intend to set - we're just lucky that they usually get ignored/overwritten We should probably put together some comprehensive benchmarks!
Regarding the part about documenting the option: what would be any use cases where one would want this default to false? I'd really like to see that option gone.

Also, how about having and (name suggestions welcome)?
This somewhat comes down to in that if the performance impact is determined to be an unreasonable burden, you keep the option off by default but have a option that is typically only enabled at CI / PR review time. I however don't feel that we need both and in this scenario, they could just be merged into one option - even if meta type-checking is switched on by default again, the option can remain to toggle the extra CI checks (recursive behaviour) without being explicitly named . But if there's no meaningful impact, there's no reason to expose an option to switch it off! Maybe? I might suggest (non-recursive) and , which are already used in . But the more I think about it, what purpose does non-recursive availability even provide? For example, some JDK stuff uses to determine whether it can use JFX, and IIRC this check only worked properly when is enabled - it produced a broken JDK on some platforms when it was off (which it is by default). The obvious use of is to check whether a derivation can be evaluated and is expected to build properly - why would you ever want to subject yourself to the false positives that crop up from the check not being recursive? Yes, non-recursive is obviously more efficient, but if you actually use it for anything, you're making assumptions that you really shouldn't be making. We should probably just scrutinize how and when availability is used rather than worrying about whether it's maximally efficient. From this perspective, is an optimization that makes unreliable and useless (and therefore shouldn't be optional), while is a superficial/sanity type check that is optional to enable when you know that all of its inputs are well-formed. One is actual functionality (or a faulty optimization depending on how you look at it) while the other is a linter pass :stuckouttongue:
I did a few greps in order to get a feeling for how this attribute is used, and was greeted with the usual chaotic inconsistency: - - Then I looked at the implementation and it should be equivalent to the output of but (a) only checking for platforms and not for other evaluation issues and (b) without the possibility to opt-in via configuration.

It kind of feels like should replaced in favor of , but I'm not ready to jump into that rabbit hole yet … But given what I've seen so far, I am in favor of always doing the recursive check in and removing the configuration option. I am not worried about big performance hits, but a quick benchmark should be performed nevertheless for good measure and to appease potential critics. The attribute from is currently not exposed, this could be however. Note that currently produces a Yes/No/Warn tri-state, we only want to expose a boolean though (Warn =true). Regarding the recursion check, instead of removing the attribute from the set I suggest removing the type check: . This should have the same effect as your solution right now (the available attribute not being evaluated prematurely), but should be more compatible with potential future type checking improvements.