The problem is the collation. MV Query expects the collation of a string-type property and its index to be either SqlString (or SPACE in older versions) for left-justified fields or MVR for right justified fields (that aren't dates or times). If the class and index had been created starting with the mv file dictionary and using PROTOCLASS and CREATE.INDEX the collation would have been created appropriately. If the class is created manually then the collation needs to be set.

I found a couple of useful notes in the documentation. At it says:

Multivalue users who upgrade their applications from a release prior to 2012.1 to 2012.1 or later may experience a slowdown in CMQL queries that had previously made use of an index. Previously, CMQL assumed the collation for left-justified strings was SPACE. It is now SQLSTRING(150). This will not match an existing index that was created with the previous default of SPACE collation.

To correct this issue, use studio to edit the class associated with the multivalue file and change the COLLATION parameter to SQLSTRING(150) on all properties that are used as index keys. Then rebuild the affected indexes.

and the documentation for CREATE.INDEX at notes:

CREATE.INDEX assigns SqlString(150) collation to both the index and the created indexfield property. 

So you need to add collation to your property and index..

Set status=server.Connect(servername,user,AccessToken) needs to be
Set status=server.Connect(servername,user,,AccessToken)

To get the token I use:


scope="openid offline_access"

The client_secret is in the post form.
code_challenge/method, nonce, and state may be optional, but desirable for security.
prompt="consent" changes how the authorization is done and probably optional.
access_type="offline" is probably optional since you have the offline_access scope.

I found that adding some additional scopes would prevent the token from working for retrieving email.

If you are using an access token, do not also send a password.

How are you getting the access token? Are you including the necessary scopes for email? You need to use scopes and (or similar) to send and receive email.

Microsoft also requires a tenant id in the request, for example:
where "common" is the tenant id for an email address, but you may need to use the tenant id for

This is on windows? The windows terminal runs as the desktop user, but the csp page is running as the IRIS superserver which doesn't have access to your windows desktop. If you look in Task Manager you will probably see an entry for your running OS application. You just can't directly interact with it. Windows XP used to show you a popup that would open the alternate desktop, but newer windows versions don't do that anymore.

Do you mean write the array to an MV file, as you can do with MATWRITE on a dimensioned array? No, not directly. MATWRITE and WRITE work with dimensioned and dynamic arrays because they have an explicit numeric sequence that maps the array elements to the attributes of a file item.

If your array is one-dimensional as in your example, you could use $ORDER in MVBASIC to traverse the array and write each element as a file item where the array subscript becomes the item id.

If you want to store the array in the database persistently, you can store it as a global with $MERGE:



$MERGE ^SOMEGLOBAL("thisdata")=C

Take a look at this article which talks about $MERGE, $ORDER, and globals in MV.

If you want to write the array to an OS file, you can use the previous suggestion of traversing with $ORDER and writing to a %Stream.File object. If the array is multidimensional, you can use objectscript $QUERY (MVBASIC doesn't support $QUERY directly).

Another option for writing to an OS file is using the %Library.Global class which has Import() and Export() methods. You can $merge your array to a temporary global, and then write that to a file using Export()

If you are coming from a Multivalue background, then documentation for the multivalue features of Cache comes with Cache, or can be found online at

If you aren't already using Multivalue, then you can use the examples of ansi terminal control sequences posted above, like

set CSI=$C(27)_"["
; optionally, you could use set CSI=$c(155)

Do a web search for "ansi control sequences" for more information. This is of course assuming that you are using a terminal that supports ansi. Cache Terminal does.

If you are going to be doing a lot of terminal control, you probably want to look into mnemonic spaces: For example, to blink:

use $io::"^%XDTM"
w /AI,"Hello ",/AA,"World"

Cache comes with 2 routines to use as mnemonic spaces, or you can create your own.

It sounds like you're using the Multivalue features of Cache. From the MV Shell prompt you can use the semicolon command to execute an MVBasic statement:

USER:; crt @(-5):"This is blinking":@(-6):" and this isn't"

From ObjectScript, you can use the MV command:

USER>mv "; crt @(-5):""This is blinking"":@(-6):"" and this isn't"""

or in ObjectScript you can use the $MVAT() function:

USER>w $MVAT(-5)_"This is blinking"_$MVAT(-6)_" and this isn't"

When you need to switch namespaces, instead of saving the current namespace and then restoring it after, you can put the code into its own method or routine and use NEW $NAMESPACE, for example:

Method KillJob(job) {
new $namespace
s $namespace="%SYS"
do whatever(job)

and the original namespace will be restored when the method exits. I think this also works inside of an old-fashioned argumentless DO block.

I don't know the answer to your question--whats the best approach for working with errorlog, but...

The %Status returned from the Compile() method only contains the first error status (of what could be a large number of errors). errorlog contains the result equivalent to calling $SYSTEM.Status.DecomposeStatus() on all the errors encountered while compiling.

errorlog is cumulative. If you call Compile() or similar methods multiple times passing the same errorlog variable, you end up with the decomposed results from all of the calls.

You could iterate over errorlog and re-compose a set of %Status values, but you already have the (single) %Status returned from Compile()

When you configure the OAuth2 server through the management portal, System>Security>OAuth2>Server, On the Customization tab you can specify a "Validate User Class" which defaults to %OAuth2.Server.Validate.

The default class validates against the system's user database. You can subclass it and override the ValidateUser method to authenticate using a different method if you want.

When you sort the DICT of a file, the file DICT.DICT is used as the dictionary, so it sounds like you have a malformed item in DICT.DICT.

Use the SEARCH command to look for FIELD.ASSOC in DICT.DICT. For example on my instance:


1  Items selected to list #0

0001 PH

so in my DICT.DICT I don't have anything with FIELD.ASSOC_ in it, but the "@" item--which is used for a default list when no attributes are referenced--has a similar name "ASSOC". Maybe your "@" entry was overwritten by one from an imported account? Also use search to look at DICT TEST because even though it isn't used by the default list, CMQL might be parsing it. If you don't find anything in DICT.DICT or DICT TEST, try looking in VOC and DICT VOC as well.